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 "pv_player_engine.h"
     19 
     20 #include "pv_player_config.h"
     21 
     22 #ifndef USE_CML2_CONFIG
     23 #include "pv_player_engine_tunables.h"
     24 #endif
     25 
     26 #include "pv_player_sdkinfo.h"
     27 
     28 #include "pvmf_node_interface.h"
     29 
     30 #include "pvmf_ffparsernode_extension.h"
     31 
     32 #include "pvmf_data_source_init_extension.h"
     33 
     34 #include "pvmf_track_selection_extension.h"
     35 
     36 #include "pvmf_data_source_playback_control.h"
     37 
     38 #include "pvmf_data_source_direction_control.h"
     39 
     40 #include "pvmf_track_level_info_extension.h"
     41 
     42 #include "pvmf_fileoutput_factory.h"
     43 
     44 #include "pvmf_fileoutput_config.h"
     45 
     46 #include "pvmf_nodes_sync_control.h"
     47 
     48 #include "pvlogger.h"
     49 
     50 #include "oscl_error_codes.h"
     51 
     52 #include "pvmf_basic_errorinfomessage.h"
     53 
     54 #include "pvmf_duration_infomessage.h"
     55 
     56 #include "pvmf_metadata_infomessage.h"
     57 
     58 #include "pv_mime_string_utils.h"
     59 
     60 #include "pvmi_kvp_util.h"
     61 
     62 #include "oscl_string_utils.h"
     63 
     64 #include "media_clock_converter.h"
     65 
     66 #include "time_comparison_utils.h"
     67 
     68 #include "pvmf_local_data_source.h"
     69 
     70 #include "pvmf_cpmplugin_license_interface.h"
     71 
     72 #include "oscl_registry_access_client.h"
     73 
     74 #include "pvmf_source_context_data.h"
     75 
     76 #include "pv_player_node_registry.h"
     77 #include "pv_player_registry_interface.h"
     78 
     79 // For recognizer registry
     80 #include "pvmf_recognizer_registry.h"
     81 
     82 #include "pvmi_datastreamsyncinterface_ref_factory.h"
     83 
     84 #include "pvmf_recognizer_plugin.h"
     85 
     86 //
     87 
     88 
     89 #define PVPLAYERENGINE_NUM_COMMANDS 10
     90 
     91 #define PVPLAYERENGINE_TIMERID_ENDTIMECHECK 1
     92 
     93 #define PVP_MIN_PLAYSTATUS_PERCENT_OVERFLOW_THRESHOLD 1000
     94 
     95 
     96 
     97 PVPlayerEngine* PVPlayerEngine::New(PVCommandStatusObserver* aCmdStatusObserver,
     98                                     PVErrorEventObserver *aErrorEventObserver,
     99                                     PVInformationalEventObserver *aInfoEventObserver,
    100                                     bool aHwAccelerated)
    101 {
    102     PVPlayerEngine* engine = NULL;
    103     engine = OSCL_NEW(PVPlayerEngine, (aHwAccelerated));
    104     if (engine)
    105     {
    106         engine->Construct(aCmdStatusObserver,
    107                           aErrorEventObserver,
    108                           aInfoEventObserver);
    109     }
    110 
    111     return engine;
    112 }
    113 
    114 
    115 PVPlayerEngine::~PVPlayerEngine()
    116 {
    117     Cancel();
    118 
    119     // Clear the Track selection List
    120     iTrackSelectionList.clear();
    121 
    122     // Remove Stored KVP Values
    123     DeleteKVPValues();
    124 
    125     if (!iPendingCmds.empty())
    126     {
    127         iPendingCmds.pop();
    128     }
    129 
    130     // Clean up the datapaths
    131     for (uint32 i = 0; i < iDatapathList.size(); ++i)
    132     {
    133         DoEngineDatapathCleanup(iDatapathList[i]);
    134     }
    135     iDatapathList.clear();
    136 
    137     // Clean up the source node
    138     DoSourceNodeCleanup();
    139 
    140     // Shutdown and destroy the timer
    141     if (iPollingCheckTimer)
    142     {
    143         iPollingCheckTimer->Clear();
    144     }
    145 
    146     if (iWatchDogTimer)
    147     {
    148         iWatchDogTimer->Cancel();
    149         OSCL_DELETE(iWatchDogTimer);
    150     }
    151 
    152     OSCL_DELETE(iPollingCheckTimer);
    153 
    154     //Destroy media clock notifications interface
    155     if (iClockNotificationsInf != NULL)
    156     {
    157         iPlaybackClock.DestroyMediaClockNotificationsInterface(iClockNotificationsInf);
    158         iClockNotificationsInf = NULL;
    159     }
    160 
    161     // Return all engine contexts to pool
    162     while (!iCurrentContextList.empty())
    163     {
    164         FreeEngineContext(iCurrentContextList[0]);
    165     }
    166 
    167     PVPlayerRegistryPopulator::Depopulate(iPlayerNodeRegistry, iPlayerRecognizerRegistry);
    168 
    169     iNodeUuids.clear();
    170 
    171     iCommandIdMut.Close();
    172     iOOTSyncCommandSem.Close();
    173 }
    174 
    175 
    176 PVCommandId PVPlayerEngine::GetSDKInfo(PVSDKInfo &aSDKInfo, const OsclAny* aContextData)
    177 {
    178     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetSDKInfo()"));
    179     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    180     paramvec.reserve(1);
    181     paramvec.clear();
    182     PVPlayerEngineCommandParamUnion param;
    183     param.pOsclAny_value = (OsclAny*) & aSDKInfo;
    184     paramvec.push_back(param);
    185     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_SDK_INFO, (OsclAny*)aContextData, &paramvec);
    186 }
    187 
    188 
    189 PVCommandId PVPlayerEngine::GetSDKModuleInfo(PVSDKModuleInfo &aSDKModuleInfo, const OsclAny* aContextData)
    190 {
    191     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetSDKModuleInfo()"));
    192     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    193     paramvec.reserve(1);
    194     paramvec.clear();
    195     PVPlayerEngineCommandParamUnion param;
    196     param.pOsclAny_value = (OsclAny*) & aSDKModuleInfo;
    197     paramvec.push_back(param);
    198     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_SDK_MODULE_INFO, (OsclAny*)aContextData, &paramvec);
    199 }
    200 
    201 
    202 PVCommandId PVPlayerEngine::SetLogAppender(const char* aTag, OsclSharedPtr<PVLoggerAppender>& aAppender, const OsclAny* aContextData)
    203 {
    204     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetLogAppender()"));
    205     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    206     paramvec.reserve(2);
    207     paramvec.clear();
    208     PVPlayerEngineCommandParamUnion param;
    209     param.pChar_value = (char*)aTag;
    210     paramvec.push_back(param);
    211     param.pOsclAny_value = (OsclAny*) & aAppender;
    212     paramvec.push_back(param);
    213     return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_LOG_APPENDER, (OsclAny*)aContextData, &paramvec);
    214 }
    215 
    216 
    217 PVCommandId PVPlayerEngine::RemoveLogAppender(const char* aTag, OsclSharedPtr<PVLoggerAppender>& aAppender, const OsclAny* aContextData)
    218 {
    219     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveLogAppender()"));
    220     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    221     paramvec.reserve(2);
    222     paramvec.clear();
    223     PVPlayerEngineCommandParamUnion param;
    224     param.pChar_value = (char*)aTag;
    225     paramvec.push_back(param);
    226     param.pOsclAny_value = (OsclAny*) & aAppender;
    227     paramvec.push_back(param);
    228     return AddCommandToQueue(PVP_ENGINE_COMMAND_REMOVE_LOG_APPENDER, (OsclAny*)aContextData, &paramvec);
    229 }
    230 
    231 
    232 PVCommandId PVPlayerEngine::SetLogLevel(const char* aTag, int32 aLevel, bool aSetSubtree, const OsclAny* aContextData)
    233 {
    234     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetLogLevel()"));
    235     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    236     paramvec.reserve(3);
    237     paramvec.clear();
    238     PVPlayerEngineCommandParamUnion param;
    239     param.pChar_value = (char*)aTag;
    240     paramvec.push_back(param);
    241     param.int32_value = aLevel;
    242     paramvec.push_back(param);
    243     param.bool_value = aSetSubtree;
    244     paramvec.push_back(param);
    245     return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_LOG_LEVEL, (OsclAny*)aContextData, &paramvec);
    246 }
    247 
    248 
    249 PVCommandId PVPlayerEngine::GetLogLevel(const char* aTag, PVLogLevelInfo& aLogInfo, const OsclAny* aContextData)
    250 {
    251     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetLogLevel()"));
    252     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    253     paramvec.reserve(2);
    254     paramvec.clear();
    255     PVPlayerEngineCommandParamUnion param;
    256     param.pChar_value = (char*)aTag;
    257     paramvec.push_back(param);
    258     param.pOsclAny_value = (OsclAny*) & aLogInfo;
    259     paramvec.push_back(param);
    260     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_LOG_LEVEL, (OsclAny*)aContextData, &paramvec);
    261 }
    262 
    263 
    264 PVCommandId PVPlayerEngine::QueryUUID(const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
    265                                       bool aExactUuidsOnly, const OsclAny* aContextData)
    266 {
    267     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::QueryUUID()"));
    268     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    269     paramvec.reserve(3);
    270     paramvec.clear();
    271     PVPlayerEngineCommandParamUnion param;
    272     param.pOsclAny_value = (OsclAny*) & aMimeType;
    273     paramvec.push_back(param);
    274     param.pOsclAny_value = (OsclAny*) & aUuids;
    275     paramvec.push_back(param);
    276     param.bool_value = aExactUuidsOnly;
    277     paramvec.push_back(param);
    278     return AddCommandToQueue(PVP_ENGINE_COMMAND_QUERY_UUID, (OsclAny*)aContextData, &paramvec);
    279 }
    280 
    281 
    282 PVCommandId PVPlayerEngine::QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContextData)
    283 {
    284     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::QueryInterface()"));
    285     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    286     paramvec.reserve(1);
    287     paramvec.clear();
    288     PVPlayerEngineCommandParamUnion param;
    289     param.pOsclAny_value = (OsclAny*) & aInterfacePtr;
    290     paramvec.push_back(param);
    291     return AddCommandToQueue(PVP_ENGINE_COMMAND_QUERY_INTERFACE, (OsclAny*)aContextData, &paramvec, &aUuid);
    292 }
    293 
    294 
    295 PVCommandId PVPlayerEngine::CancelCommand(PVCommandId aCancelCmdId, const OsclAny* aContextData)
    296 {
    297     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CancelCommand()"));
    298     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    299     paramvec.reserve(1);
    300     paramvec.clear();
    301     PVPlayerEngineCommandParamUnion param;
    302     param.int32_value = aCancelCmdId;
    303     paramvec.push_back(param);
    304     return AddCommandToQueue(PVP_ENGINE_COMMAND_CANCEL_COMMAND, (OsclAny*)aContextData, &paramvec);
    305 }
    306 
    307 
    308 PVCommandId PVPlayerEngine::CancelAllCommands(const OsclAny* aContextData)
    309 {
    310     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CancelAllCommands()"));
    311     return AddCommandToQueue(PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS, (OsclAny*)aContextData);
    312 }
    313 
    314 
    315 PVCommandId PVPlayerEngine::GetPVPlayerState(PVPlayerState& aState, const OsclAny* aContextData)
    316 {
    317     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPVPlayerState()"));
    318     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    319     paramvec.reserve(1);
    320     paramvec.clear();
    321     PVPlayerEngineCommandParamUnion param;
    322     param.pOsclAny_value = (OsclAny*) & aState;
    323     paramvec.push_back(param);
    324     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE, (OsclAny*)aContextData, &paramvec);
    325 }
    326 
    327 
    328 PVMFStatus PVPlayerEngine::GetPVPlayerStateSync(PVPlayerState& aState)
    329 {
    330     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPVPlayerStateSync()"));
    331     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    332     paramvec.reserve(1);
    333     paramvec.clear();
    334     PVPlayerEngineCommandParamUnion param;
    335     param.pOsclAny_value = (OsclAny*) & aState;
    336     paramvec.push_back(param);
    337     if (iThreadSafeQueue.IsInThread())
    338     {
    339         PVPlayerEngineCommand cmd(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE, -1, NULL, &paramvec);
    340         return DoGetPVPlayerState(cmd, true);
    341     }
    342     else
    343     {
    344         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE_OOTSYNC, &paramvec);
    345     }
    346 }
    347 
    348 
    349 PVCommandId PVPlayerEngine::AddDataSource(PVPlayerDataSource& aDataSource, const OsclAny* aContextData)
    350 {
    351     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AddDataSource()"));
    352     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    353     paramvec.reserve(1);
    354     paramvec.clear();
    355     PVPlayerEngineCommandParamUnion param;
    356     param.pOsclAny_value = (OsclAny*) & aDataSource;
    357     paramvec.push_back(param);
    358     return AddCommandToQueue(PVP_ENGINE_COMMAND_ADD_DATA_SOURCE, (OsclAny*)aContextData, &paramvec);
    359 }
    360 
    361 
    362 PVCommandId PVPlayerEngine::Init(const OsclAny* aContextData)
    363 {
    364     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Init()"));
    365     return AddCommandToQueue(PVP_ENGINE_COMMAND_INIT, (OsclAny*)aContextData);
    366 }
    367 
    368 
    369 PVCommandId PVPlayerEngine::GetMetadataKeys(PVPMetadataList& aKeyList, int32 aStartingIndex, int32 aMaxEntries,
    370         char* aQueryKey, const OsclAny* aContextData)
    371 {
    372     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetMetadataKeys()"));
    373     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    374     paramvec.reserve(4);
    375     paramvec.clear();
    376     PVPlayerEngineCommandParamUnion param;
    377 
    378     param.pOsclAny_value = (OsclAny*) & aKeyList;
    379     paramvec.push_back(param);
    380     param.int32_value = aStartingIndex;
    381     paramvec.push_back(param);
    382     param.int32_value = aMaxEntries;
    383     paramvec.push_back(param);
    384     param.pChar_value = aQueryKey;
    385     paramvec.push_back(param);
    386 
    387     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_METADATA_KEY, (OsclAny*)aContextData, &paramvec);
    388 }
    389 
    390 PVCommandId PVPlayerEngine::GetMetadataValues(PVPMetadataList& aKeyList, int32 aStartingValueIndex, int32 aMaxValueEntries, int32& aNumAvailableValueEntries,
    391         Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, const OsclAny* aContextData, bool aMetadataValuesCopiedInCallBack)
    392 {
    393     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetMetadataValues()"));
    394     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    395     paramvec.reserve(6);
    396     paramvec.clear();
    397     PVPlayerEngineCommandParamUnion param;
    398 
    399     param.pOsclAny_value = (OsclAny*) & aKeyList;
    400     paramvec.push_back(param);
    401     param.int32_value = aStartingValueIndex;
    402     paramvec.push_back(param);
    403     param.int32_value = aMaxValueEntries;
    404     paramvec.push_back(param);
    405     param.pOsclAny_value = (OsclAny*) & aNumAvailableValueEntries;
    406     paramvec.push_back(param);
    407     param.pOsclAny_value = (OsclAny*) & aValueList;
    408     paramvec.push_back(param);
    409     param.bool_value = aMetadataValuesCopiedInCallBack;
    410     paramvec.push_back(param);
    411 
    412     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_METADATA_VALUE, (OsclAny*)aContextData, &paramvec);
    413 }
    414 
    415 PVCommandId PVPlayerEngine::ReleaseMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, const OsclAny* aContextData)
    416 {
    417     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ReleaseMetadataValues()"));
    418     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    419     paramvec.reserve(1);
    420     paramvec.clear();
    421     PVPlayerEngineCommandParamUnion param;
    422 
    423     param.pOsclAny_value = (OsclAny*) & aValueList;
    424     paramvec.push_back(param);
    425 
    426     return AddCommandToQueue(PVP_ENGINE_COMMAND_RELEASE_METADATA_VALUE, (OsclAny*)aContextData, &paramvec);
    427 }
    428 
    429 PVCommandId PVPlayerEngine::AddDataSink(PVPlayerDataSink& aDataSink, const OsclAny* aContextData)
    430 {
    431     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AddDataSink()"));
    432     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    433     paramvec.reserve(1);
    434     paramvec.clear();
    435     PVPlayerEngineCommandParamUnion param;
    436     param.pOsclAny_value = (OsclAny*) & aDataSink;
    437     paramvec.push_back(param);
    438     return AddCommandToQueue(PVP_ENGINE_COMMAND_ADD_DATA_SINK, (OsclAny*)aContextData, &paramvec);
    439 }
    440 
    441 
    442 PVCommandId PVPlayerEngine::SetPlaybackRange(PVPPlaybackPosition aBeginPos, PVPPlaybackPosition aEndPos, bool aQueueRange, const OsclAny* aContextData)
    443 {
    444     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetPlaybackRange()"));
    445     PVPPlaybackPosition curpos;
    446     curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
    447 
    448     // Additional checks to ensure a valid mode is
    449     // used for the begin position.
    450     // Assumes: aBegin.iPosUnit is always valid (when applicable).
    451 
    452     // Check 1 || Check 2
    453     // Check 1: Is the begin position indeterminate?
    454     // Check 2: Is the position unit something other than playlist?
    455     // If so, set mode to NOW.
    456     if ((aBeginPos.iIndeterminate) || (aBeginPos.iPosUnit != PVPPBPOSUNIT_PLAYLIST))
    457     {
    458         aBeginPos.iMode = PVPPBPOS_MODE_NOW;
    459     }
    460     // Check 3: Is the position unit playlist and the mode something other than the three valid
    461     // modes? If so, set mode to NOW.
    462     else if (aBeginPos.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
    463     {
    464         switch (aBeginPos.iMode)
    465         {
    466             case PVPPBPOS_MODE_NOW:
    467             case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT:
    468             case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION:
    469                 break;
    470             case PVPPBPOS_MODE_UNKNOWN:
    471             default:
    472                 aBeginPos.iMode = PVPPBPOS_MODE_NOW;
    473                 break;
    474         }
    475     }
    476     iPlaybackPositionMode = aBeginPos.iMode;
    477     GetPlaybackClockPosition(curpos);
    478     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    479     paramvec.reserve(3);
    480     paramvec.clear();
    481     PVPlayerEngineCommandParamUnion param;
    482     param.playbackpos_value = aBeginPos;
    483     paramvec.push_back(param);
    484     param.playbackpos_value = aEndPos;
    485     paramvec.push_back(param);
    486     param.bool_value = aQueueRange;
    487     paramvec.push_back(param);
    488     if (!iOverflowFlag)
    489     {
    490         return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE, (OsclAny*)aContextData, &paramvec);
    491     }
    492     else
    493     {
    494         return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE, (OsclAny*)aContextData, &paramvec, NULL, false);
    495     }
    496 }
    497 
    498 
    499 PVCommandId PVPlayerEngine::GetPlaybackRange(PVPPlaybackPosition &aBeginPos, PVPPlaybackPosition &aEndPos, bool aQueued, const OsclAny* aContextData)
    500 {
    501     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPlaybackRange()"));
    502     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    503     paramvec.reserve(3);
    504     paramvec.clear();
    505     PVPlayerEngineCommandParamUnion param;
    506     param.pPlaybackpos_value = &aBeginPos;
    507     paramvec.push_back(param);
    508     param.pPlaybackpos_value = &aEndPos;
    509     paramvec.push_back(param);
    510     param.bool_value = aQueued;
    511     paramvec.push_back(param);
    512     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PLAYBACK_RANGE, (OsclAny*)aContextData, &paramvec);
    513 }
    514 
    515 
    516 PVCommandId PVPlayerEngine::GetCurrentPosition(PVPPlaybackPosition &aPos, const OsclAny* aContextData)
    517 {
    518     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetCurrentPosition()"));
    519     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    520     paramvec.clear();
    521     PVPlayerEngineCommandParamUnion param;
    522     param.pPlaybackpos_value = &aPos;
    523     paramvec.push_back(param);
    524     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION, (OsclAny*)aContextData, &paramvec);
    525 }
    526 
    527 
    528 PVMFStatus PVPlayerEngine::GetCurrentPositionSync(PVPPlaybackPosition &aPos)
    529 {
    530     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetCurrentPositionSync()"));
    531     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    532     paramvec.reserve(1);
    533     paramvec.clear();
    534     PVPlayerEngineCommandParamUnion param;
    535     param.pPlaybackpos_value = &aPos;
    536     paramvec.push_back(param);
    537     if (iThreadSafeQueue.IsInThread())
    538     {
    539         PVPlayerEngineCommand cmd(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION, -1, NULL, &paramvec);
    540         return DoGetCurrentPosition(cmd, true);
    541     }
    542     else
    543     {
    544         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION_OOTSYNC, &paramvec);
    545     }
    546 }
    547 
    548 
    549 PVCommandId PVPlayerEngine::SetPlaybackRate(int32 aRate, PVMFTimebase* aTimebase, const OsclAny* aContextData)
    550 {
    551     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetPlaybackRate()"));
    552     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    553     paramvec.reserve(2);
    554     paramvec.clear();
    555     PVPlayerEngineCommandParamUnion param;
    556     param.int32_value = aRate;
    557     paramvec.push_back(param);
    558     param.pOsclAny_value = (OsclAny*)aTimebase;
    559     paramvec.push_back(param);
    560     return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RATE, (OsclAny*)aContextData, &paramvec);
    561 }
    562 
    563 
    564 PVCommandId PVPlayerEngine::GetPlaybackRate(int32& aRate, PVMFTimebase*& aTimebase, const OsclAny* aContextData)
    565 {
    566     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPlaybackRate()"));
    567     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    568     paramvec.reserve(2);
    569     paramvec.clear();
    570     PVPlayerEngineCommandParamUnion param;
    571     param.pInt32_value = &aRate;
    572     paramvec.push_back(param);
    573     param.pOsclAny_value = (OsclAny*) & aTimebase;
    574     paramvec.push_back(param);
    575     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PLAYBACK_RATE, (OsclAny*)aContextData, &paramvec);
    576 }
    577 
    578 
    579 PVCommandId PVPlayerEngine::GetPlaybackMinMaxRate(int32& aMinRate, int32& aMaxRate, const OsclAny* aContextData)
    580 {
    581     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPlaybackMinMaxRate()"));
    582     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    583     paramvec.reserve(2);
    584     paramvec.clear();
    585     PVPlayerEngineCommandParamUnion param;
    586     param.pInt32_value = &aMinRate;
    587     paramvec.push_back(param);
    588     param.pInt32_value = &aMaxRate;
    589     paramvec.push_back(param);
    590     return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PLAYBACK_MINMAX_RATE, (OsclAny*)aContextData, &paramvec);
    591 }
    592 
    593 
    594 PVCommandId PVPlayerEngine::Prepare(const OsclAny* aContextData)
    595 {
    596     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Prepare()"));
    597     return AddCommandToQueue(PVP_ENGINE_COMMAND_PREPARE, (OsclAny*)aContextData);
    598 }
    599 
    600 
    601 PVCommandId PVPlayerEngine::Start(const OsclAny* aContextData)
    602 {
    603     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Start() "));
    604     return AddCommandToQueue(PVP_ENGINE_COMMAND_START, (OsclAny*)aContextData);
    605 }
    606 
    607 
    608 PVCommandId PVPlayerEngine::Pause(const OsclAny* aContextData)
    609 {
    610     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Pause()"));
    611     return AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE, (OsclAny*)aContextData);
    612 }
    613 
    614 
    615 PVCommandId PVPlayerEngine::Resume(const OsclAny* aContextData)
    616 {
    617     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Resume()"));
    618     return AddCommandToQueue(PVP_ENGINE_COMMAND_RESUME, (OsclAny*)aContextData);
    619 }
    620 
    621 
    622 PVCommandId PVPlayerEngine::Stop(const OsclAny* aContextData)
    623 {
    624     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Stop()"));
    625     return AddCommandToQueue(PVP_ENGINE_COMMAND_STOP, (OsclAny*)aContextData);
    626 }
    627 
    628 
    629 PVCommandId PVPlayerEngine::RemoveDataSink(PVPlayerDataSink& aDataSink, const OsclAny* aContextData)
    630 {
    631     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSink()"));
    632     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    633     paramvec.reserve(1);
    634     paramvec.clear();
    635     PVPlayerEngineCommandParamUnion param;
    636     param.pOsclAny_value = (OsclAny*) & aDataSink;
    637     paramvec.push_back(param);
    638     return AddCommandToQueue(PVP_ENGINE_COMMAND_REMOVE_DATA_SINK, (OsclAny*)aContextData, &paramvec);
    639 }
    640 
    641 
    642 PVCommandId PVPlayerEngine::Reset(const OsclAny* aContextData)
    643 {
    644     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Reset()"));
    645     return AddCommandToQueue(PVP_ENGINE_COMMAND_RESET, (OsclAny*)aContextData);
    646 }
    647 
    648 
    649 PVCommandId PVPlayerEngine::RemoveDataSource(PVPlayerDataSource& aDataSource, const OsclAny* aContextData)
    650 {
    651     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSource()"));
    652     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    653     paramvec.reserve(1);
    654     paramvec.clear();
    655     PVPlayerEngineCommandParamUnion param;
    656     param.pOsclAny_value = (OsclAny*) & aDataSource;
    657     paramvec.push_back(param);
    658     return AddCommandToQueue(PVP_ENGINE_COMMAND_REMOVE_DATA_SOURCE, (OsclAny*)aContextData, &paramvec);
    659 }
    660 
    661 
    662 void PVPlayerEngine::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
    663 {
    664     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setObserver()"));
    665 
    666     if (iThreadSafeQueue.IsInThread())
    667     {
    668         iCfgCapCmdObserver = aObserver;
    669     }
    670     else
    671     {
    672         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    673         paramvec.reserve(2);
    674         paramvec.clear();
    675         PVPlayerEngineCommandParamUnion param;
    676         param.pOsclAny_value = aObserver;
    677         paramvec.push_back(param);
    678         DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_SET_OBSERVER_OOTSYNC, &paramvec);
    679     }
    680 }
    681 
    682 PVMFStatus PVPlayerEngine::DoSetObserverSync(PVPlayerEngineCommand& aCmd)
    683 {
    684     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetObserverSync() In"));
    685 
    686     iCfgCapCmdObserver = (PvmiConfigAndCapabilityCmdObserver*)(aCmd.GetParam(0).pOsclAny_value);
    687 
    688     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetObserverSync() Out"));
    689     return PVMFSuccess;
    690 }
    691 
    692 PVMFStatus PVPlayerEngine::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
    693 {
    694     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::getParametersSync()"));
    695     OSCL_UNUSED_ARG(aSession);
    696 
    697     if (iThreadSafeQueue.IsInThread())
    698     {
    699         return DoCapConfigGetParametersSync(aIdentifier, aParameters, aNumParamElements, aContext);
    700     }
    701     else
    702     {
    703         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    704         paramvec.reserve(5);
    705         paramvec.clear();
    706         PVPlayerEngineCommandParamUnion param;
    707         param.pOsclAny_value = &aIdentifier;
    708         paramvec.push_back(param);
    709         param.pOsclAny_value = &aParameters;
    710         paramvec.push_back(param);
    711         param.pOsclAny_value = &aNumParamElements;
    712         paramvec.push_back(param);
    713         param.pOsclAny_value = &aContext;
    714         paramvec.push_back(param);
    715         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_GET_PARAMETERS_OOTSYNC, &paramvec);
    716     }
    717 }
    718 
    719 
    720 PVMFStatus PVPlayerEngine::DoGetParametersSync(PVPlayerEngineCommand& aCmd)
    721 {
    722     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetParametersSync() In"));
    723 
    724     PVMFStatus status = DoCapConfigGetParametersSync(
    725                             *((PvmiKeyType*)aCmd.GetParam(0).pOsclAny_value)
    726                             , *((PvmiKvp**)aCmd.GetParam(1).pOsclAny_value)
    727                             , *((int*)aCmd.GetParam(2).pOsclAny_value)
    728                             , *((PvmiCapabilityContext*)aCmd.GetParam(3).pOsclAny_value));
    729 
    730     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetParametersSync() Out"));
    731     return status;
    732 }
    733 
    734 
    735 PVMFStatus PVPlayerEngine::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
    736 {
    737     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::releaseParameters()"));
    738     OSCL_UNUSED_ARG(aSession);
    739 
    740     if (iThreadSafeQueue.IsInThread())
    741     {
    742         return DoCapConfigReleaseParameters(aParameters, aNumElements);
    743     }
    744     else
    745     {
    746         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    747         paramvec.reserve(3);
    748         paramvec.clear();
    749         PVPlayerEngineCommandParamUnion param;
    750         param.pOsclAny_value = aParameters;
    751         paramvec.push_back(param);
    752         param.int32_value = aNumElements;
    753         paramvec.push_back(param);
    754         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_RELEASE_PARAMETERS_OOTSYNC, &paramvec);
    755     }
    756 }
    757 
    758 PVMFStatus PVPlayerEngine::DoReleaseParametersSync(PVPlayerEngineCommand& aCmd)
    759 {
    760     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReleaseParametersSync() In"));
    761 
    762     PVMFStatus status = DoCapConfigReleaseParameters(
    763                             (PvmiKvp*)aCmd.GetParam(0).pOsclAny_value
    764                             , aCmd.GetParam(1).int32_value);
    765 
    766     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReleaseParametersSync() Out"));
    767     return status;
    768 }
    769 
    770 void PVPlayerEngine::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
    771 {
    772     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::createContext()"));
    773     OSCL_UNUSED_ARG(aSession);
    774     // Context is not really supported so just return some member variable pointer
    775     aContext = (PvmiCapabilityContext) & iCapConfigContext;
    776 }
    777 
    778 
    779 void PVPlayerEngine::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements)
    780 {
    781     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setContextParameters()"));
    782     OSCL_UNUSED_ARG(aSession);
    783     OSCL_UNUSED_ARG(aContext);
    784     OSCL_UNUSED_ARG(aParameters);
    785     OSCL_UNUSED_ARG(aNumParamElements);
    786     // This method is not supported so leave
    787     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::setContextParameters() is not supported!"));
    788     OSCL_LEAVE(OsclErrNotSupported);
    789 }
    790 
    791 
    792 void PVPlayerEngine::DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
    793 {
    794     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DeleteContext()"));
    795     OSCL_UNUSED_ARG(aSession);
    796     OSCL_UNUSED_ARG(aContext);
    797     // Do nothing since the context is just the a member variable of the engine
    798 }
    799 
    800 
    801 void PVPlayerEngine::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
    802 {
    803     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setParametersSync()"));
    804     OSCL_UNUSED_ARG(aSession);
    805 
    806     // Save the parameters in an engine command object
    807     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    808     paramvec.reserve(3);
    809     paramvec.clear();
    810     PVPlayerEngineCommandParamUnion param;
    811     param.pOsclAny_value = (OsclAny*)aParameters;
    812     paramvec.push_back(param);
    813     param.int32_value = (int32) aNumElements;
    814     paramvec.push_back(param);
    815     param.pOsclAny_value = (OsclAny*) & aRetKVP;
    816     paramvec.push_back(param);
    817     if (iThreadSafeQueue.IsInThread())
    818     {
    819         PVPlayerEngineCommand cmd(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS, -1, NULL, &paramvec);
    820 
    821         // Complete the request synchronously
    822         DoCapConfigSetParameters(cmd, true);
    823     }
    824     else
    825     {
    826         DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS_OOTSYNC, &paramvec);
    827     }
    828 }
    829 
    830 
    831 PVMFCommandId PVPlayerEngine::setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext)
    832 {
    833     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setParametersAsync()"));
    834     OSCL_UNUSED_ARG(aSession);
    835 
    836     // Save the parameters in an engine command object
    837     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    838     paramvec.reserve(3);
    839     paramvec.clear();
    840     PVPlayerEngineCommandParamUnion param;
    841     param.pOsclAny_value = (OsclAny*)aParameters;
    842     paramvec.push_back(param);
    843     param.int32_value = (int32) aNumElements;
    844     paramvec.push_back(param);
    845     param.pOsclAny_value = (OsclAny*) & aRetKVP;
    846     paramvec.push_back(param);
    847 
    848     // Push it to command queue to be processed asynchronously
    849     return AddCommandToQueue(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS, (OsclAny*)aContext, &paramvec, NULL, false);
    850 }
    851 
    852 
    853 uint32 PVPlayerEngine::getCapabilityMetric(PvmiMIOSession aSession)
    854 {
    855     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::getCapabilityMetric()"));
    856     OSCL_UNUSED_ARG(aSession);
    857     // Not supported so return 0
    858     return 0;
    859 }
    860 
    861 
    862 PVMFStatus PVPlayerEngine::verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
    863 {
    864     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::verifyParametersSync()"));
    865     OSCL_UNUSED_ARG(aSession);
    866 
    867     if (iThreadSafeQueue.IsInThread())
    868     {
    869         return DoCapConfigVerifyParameters(aParameters, aNumElements);
    870     }
    871     else
    872     {
    873         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    874         paramvec.reserve(3);
    875         paramvec.clear();
    876         PVPlayerEngineCommandParamUnion param;
    877         param.pOsclAny_value = aParameters;
    878         paramvec.push_back(param);
    879         param.int32_value = aNumElements;
    880         paramvec.push_back(param);
    881         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_VERIFY_PARAMETERS_OOTSYNC, &paramvec);
    882     }
    883 }
    884 
    885 PVMFStatus PVPlayerEngine::DoVerifyParametersSync(PVPlayerEngineCommand& aCmd)
    886 {
    887     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyParametersSync() In"));
    888 
    889     PVMFStatus status = DoCapConfigVerifyParameters(
    890                             (PvmiKvp*)aCmd.GetParam(0).pOsclAny_value
    891                             , aCmd.GetParam(1).int32_value);
    892 
    893     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyParametersSync() Out"));
    894     return status;
    895 }
    896 
    897 PVMFCommandId PVPlayerEngine::AcquireLicense(OsclAny* aLicenseData, uint32 aDataSize, oscl_wchar* aContentName, int32 aTimeoutMsec, const OsclAny* aContextData)
    898 {
    899     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AcquireLicense() wchar"));
    900     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    901     paramvec.reserve(3);
    902     paramvec.clear();
    903     PVPlayerEngineCommandParamUnion param;
    904     param.pOsclAny_value = aLicenseData;
    905     paramvec.push_back(param);
    906     param.uint32_value = aDataSize;
    907     paramvec.push_back(param);
    908     param.pWChar_value = aContentName;
    909     paramvec.push_back(param);
    910     param.int32_value = aTimeoutMsec;
    911     paramvec.push_back(param);
    912     return AddCommandToQueue(PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR, (OsclAny*)aContextData, &paramvec);
    913 }
    914 
    915 
    916 PVMFCommandId PVPlayerEngine::AcquireLicense(OsclAny* aLicenseData, uint32 aDataSize, char* aContentName, int32 aTimeoutMsec, const OsclAny* aContextData)
    917 {
    918     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AcquireLicense() char"));
    919     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    920     paramvec.reserve(3);
    921     paramvec.clear();
    922     PVPlayerEngineCommandParamUnion param;
    923     param.pOsclAny_value = aLicenseData;
    924     paramvec.push_back(param);
    925     param.uint32_value = aDataSize;
    926     paramvec.push_back(param);
    927     param.pChar_value = aContentName;
    928     paramvec.push_back(param);
    929     param.int32_value = aTimeoutMsec;
    930     paramvec.push_back(param);
    931     return AddCommandToQueue(PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR, (OsclAny*)aContextData, &paramvec);
    932 }
    933 
    934 PVMFCommandId PVPlayerEngine::CancelAcquireLicense(PVMFCommandId aCmdId, const OsclAny* aContextData)
    935 {
    936     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CancelAcquireLicense()"));
    937     Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    938     paramvec.reserve(1);
    939     paramvec.clear();
    940     PVPlayerEngineCommandParamUnion param;
    941     param.int32_value = aCmdId;
    942     paramvec.push_back(param);
    943     return AddCommandToQueue(PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE, (OsclAny*)aContextData, &paramvec);
    944 }
    945 
    946 PVMFStatus PVPlayerEngine::GetLicenseStatus(PVMFCPMLicenseStatus& aStatus)
    947 {
    948     if (iThreadSafeQueue.IsInThread())
    949     {
    950         if (iSourceNodeCPMLicenseIF)
    951             return iSourceNodeCPMLicenseIF->GetLicenseStatus(aStatus);
    952         return PVMFFailure;
    953     }
    954     else
    955     {
    956         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
    957         paramvec.reserve(2);
    958         paramvec.clear();
    959         PVPlayerEngineCommandParamUnion param;
    960         param.pOsclAny_value = &aStatus;
    961         paramvec.push_back(param);
    962         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_LICENSE_STATUS_OOTSYNC, &paramvec);
    963     }
    964 }
    965 
    966 PVMFStatus PVPlayerEngine::DoGetLicenseStatusSync(PVPlayerEngineCommand& aCmd)
    967 {
    968     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLicenseStatusSync() In"));
    969 
    970     PVMFStatus status;
    971     PVMFCPMLicenseStatus* licstatus = (PVMFCPMLicenseStatus*)(aCmd.GetParam(0).pOsclAny_value);
    972     if (!licstatus)
    973     {
    974         return PVMFFailure;
    975     }
    976 
    977     if (iSourceNodeCPMLicenseIF)
    978         status = iSourceNodeCPMLicenseIF->GetLicenseStatus(*licstatus);
    979     else
    980         status = PVMFFailure;
    981 
    982     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLicenseStatusSync() Out"));
    983     return status;
    984 }
    985 
    986 void PVPlayerEngine::addRef()
    987 {
    988 }
    989 
    990 
    991 void PVPlayerEngine::removeRef()
    992 {
    993 }
    994 
    995 
    996 bool PVPlayerEngine::queryInterface(const PVUuid& uuid, PVInterface*& iface)
    997 {
    998     if (uuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
    999     {
   1000         PvmiCapabilityAndConfig* capconfigiface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
   1001         iface = OSCL_STATIC_CAST(PVInterface*, capconfigiface);
   1002     }
   1003     else if (uuid == PVPlayerLicenseAcquisitionInterfaceUuid)
   1004     {
   1005         PVPlayerLicenseAcquisitionInterface* licacqiface = OSCL_STATIC_CAST(PVPlayerLicenseAcquisitionInterface*, this);
   1006         iface = OSCL_STATIC_CAST(PVInterface*, licacqiface);
   1007     }
   1008     // Check if track level info IF from source node was requested
   1009     else if (uuid == PVMF_TRACK_LEVEL_INFO_INTERFACE_UUID && iSourceNodeTrackLevelInfoIF)
   1010     {
   1011         iface = OSCL_STATIC_CAST(PVInterface*, iSourceNodeTrackLevelInfoIF);
   1012     }
   1013     //Check if track selection IF from source node was requested
   1014     else if (uuid == PVPlayerTrackSelectionInterfaceUuid)
   1015     {
   1016         PVPlayerTrackSelectionInterface* tseliface = OSCL_STATIC_CAST(PVPlayerTrackSelectionInterface*, this);
   1017         iface = OSCL_STATIC_CAST(PVInterface*, tseliface);
   1018     }
   1019     else
   1020     {
   1021         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::queryInterface() Unsupported interface UUID."));
   1022         return false;
   1023     }
   1024 
   1025     return true;
   1026 }
   1027 
   1028 
   1029 
   1030 PVPlayerEngine::PVPlayerEngine(bool aHwAccelerated) :
   1031         iHwAccelerated(aHwAccelerated),
   1032         OsclTimerObject(OsclActiveObject::EPriorityNominal, "PVPlayerEngine"),
   1033         iCommandId(0),
   1034         iState(PVP_ENGINE_STATE_IDLE),
   1035         iCmdStatusObserver(NULL),
   1036         iErrorEventObserver(NULL),
   1037         iInfoEventObserver(NULL),
   1038         iCfgCapCmdObserver(NULL),
   1039         iPollingCheckTimer(NULL),
   1040         iCommandCompleteStatusInErrorHandling(PVMFSuccess),
   1041         iCommandCompleteErrMsgInErrorHandling(NULL),
   1042         iCapConfigContext(0),
   1043         iNumPendingNodeCmd(0),
   1044         iNumPendingSkipCompleteEvent(0),
   1045         iNumPendingDatapathCmd(0),
   1046         iNumPVMFInfoStartOfDataPending(0),
   1047         iDataSource(NULL),
   1048         iSourceFormatType(PVMF_MIME_FORMAT_UNKNOWN),
   1049         iSourceNode(NULL),
   1050         iSourceNodeSessionId(0),
   1051         iSourceNodeInitIF(NULL),
   1052         iSourceNodeTrackSelIF(NULL),
   1053         iSourceNodePBCtrlIF(NULL),
   1054         iSourceNodeDirCtrlIF(NULL),
   1055         iSourceNodeTrackLevelInfoIF(NULL),
   1056         iSourceNodeMetadataExtIF(NULL),
   1057         iSourceNodeCapConfigIF(NULL),
   1058         iSourceNodeRegInitIF(NULL),
   1059         iSourceNodeCPMLicenseIF(NULL),
   1060         iSourceNodePVInterfaceInit(NULL),
   1061         iSourceNodePVInterfaceTrackSel(NULL),
   1062         iSourceNodePVInterfacePBCtrl(NULL),
   1063         iSourceNodePVInterfaceDirCtrl(NULL),
   1064         iSourceNodePVInterfaceTrackLevelInfo(NULL),
   1065         iSourceNodePVInterfaceMetadataExt(NULL),
   1066         iSourceNodePVInterfaceCapConfig(NULL),
   1067         iSourceNodePVInterfaceRegInit(NULL),
   1068         iSourceNodePVInterfaceCPMLicense(NULL),
   1069         iCPMGetLicenseCmdId(0),
   1070         iMetadataValuesCopiedInCallBack(true),
   1071         iReleaseMetadataValuesPending(false),
   1072         iCurrentContextListMemPool(12),
   1073         iNumberCancelCmdPending(0),
   1074         iLogger(NULL),
   1075         iReposLogger(NULL),
   1076         iPerfLogger(NULL),
   1077         iClockNotificationsInf(NULL),
   1078         iPlayStatusCallbackTimerID(0),
   1079         iPlayStatusCallbackTimerMarginWindow(0),
   1080         iCurrCallbackTimerLatency(0),
   1081         iPlaybackClockRate(100000),
   1082         iOutsideTimebase(NULL),
   1083         iPlaybackClockRate_New(100000),
   1084         iOutsideTimebase_New(NULL),
   1085         iPlaybackDirection(1),
   1086         iPlaybackDirection_New(1),
   1087         iChangePlaybackDirectionWhenResuming(false),
   1088         iEndTimeCheckEnabled(false),
   1089         iQueuedRangePresent(false),
   1090         iChangePlaybackPositionWhenResuming(false),
   1091         iActualNPT(0),
   1092         iTargetNPT(0),
   1093         iActualMediaDataTS(0),
   1094         iSkipMediaDataTS(0),
   1095         iStartNPT(0),
   1096         iStartMediaDataTS(0),
   1097         iWatchDogTimerInterval(0),
   1098         iSeekPointBeforeTargetNPT(0),
   1099         iSeekPointAfterTargetNPT(0),
   1100         iForwardReposFlag(false),
   1101         iBackwardReposFlag(false),
   1102         iPlayStatusTimerEnabled(false),
   1103         iDataReadySent(false),
   1104         iPlaybackPausedDueToEndOfClip(false),
   1105         iSourceDurationAvailable(false),
   1106         iSourceDurationInMS(0),
   1107         iPBPosEnable(true),
   1108         iPBPosStatusUnit(PVPLAYERENGINE_CONFIG_PBPOSSTATUSUNIT_DEF),
   1109         iPBPosStatusInterval(PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_DEF),
   1110         iEndTimeCheckInterval(PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_DEF),
   1111         iSeekToSyncPoint(PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINT_DEF),
   1112         iSkipToRequestedPosition(PVPLAYERENGINE_CONFIG_SKIPTOREQUESTEDPOS_DEF),
   1113         iBackwardRepos(false),
   1114         iSyncPointSeekWindow(PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_DEF),
   1115         iNodeCmdTimeout(PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_DEF),
   1116         iNodeDataQueuingTimeout(PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_DEF),
   1117         iProdInfoProdName(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PRODNAME_STRING)),
   1118         iProdInfoPartNum(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PARTNUM_STRING)),
   1119         iProdInfoHWPlatform(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_HWPLATFORM_STRING)),
   1120         iProdInfoSWPlatform(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_SWPLATFORM_STRING)),
   1121         iProdInfoDevice(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_DEVICE_STRING)),
   1122         iStreamID(0),
   1123         iAlternateSrcFormatIndex(0),
   1124         iRollOverState(RollOverStateIdle),
   1125         iTrackSelectionHelper(NULL),
   1126         iPlaybackPositionMode(PVPPBPOS_MODE_UNKNOWN),
   1127         iOverflowFlag(false)
   1128 {
   1129     iCurrentBeginPosition.iIndeterminate = true;
   1130     iCurrentEndPosition.iIndeterminate = true;
   1131     iCurrentBeginPosition.iPlayListUri = NULL;
   1132     iQueuedBeginPosition.iIndeterminate = true;
   1133     iQueuedEndPosition.iIndeterminate = true;
   1134     iChangeDirectionNPT.iIndeterminate = true;
   1135 
   1136     iSyncMarginVideo.min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
   1137     iSyncMarginVideo.max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
   1138     iSyncMarginAudio.min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
   1139     iSyncMarginAudio.max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
   1140     iSyncMarginText.min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
   1141     iSyncMarginText.max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
   1142 
   1143     iNodeUuids.clear();
   1144 }
   1145 
   1146 
   1147 void PVPlayerEngine::Construct(PVCommandStatusObserver* aCmdStatusObserver,
   1148                                PVErrorEventObserver *aErrorEventObserver,
   1149                                PVInformationalEventObserver *aInfoEventObserver)
   1150 {
   1151     iCommandIdMut.Create();
   1152     iOOTSyncCommandSem.Create();
   1153     iThreadSafeQueue.Configure(this);
   1154 
   1155     iCmdStatusObserver = aCmdStatusObserver;
   1156     iInfoEventObserver = aInfoEventObserver;
   1157     iErrorEventObserver = aErrorEventObserver;
   1158 
   1159     // Allocate memory for vectors
   1160     // If a leave occurs, let it bubble up
   1161     iCurrentCmd.reserve(1);
   1162     iCmdToCancel.reserve(1);
   1163     iCmdToDlaCancel.reserve(1);
   1164     iPendingCmds.reserve(PVPLAYERENGINE_NUM_COMMANDS);
   1165     iPvmiKvpCapNConfig.reserve(20);
   1166 
   1167     iDatapathList.reserve(3);
   1168 
   1169     iCurrentContextList.reserve(12);
   1170 
   1171     iMetadataIFList.reserve(6);
   1172     iMetadataIFList.clear();
   1173 
   1174     iMetadataKeyReleaseList.reserve(6);
   1175     iMetadataKeyReleaseList.clear();
   1176 
   1177     iMetadataValueReleaseList.reserve(6);
   1178     iMetadataValueReleaseList.clear();
   1179 
   1180     AddToScheduler();
   1181 
   1182     // Retrieve the logger object
   1183     iLogger = PVLogger::GetLoggerObject("PVPlayerEngine");
   1184     iPerfLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.perf.engine");
   1185     iReposLogger = PVLogger::GetLoggerObject("pvplayerrepos.engine");
   1186 
   1187     // Initialize the playback clock to use tickcount timebase
   1188     iPlaybackClock.SetClockTimebase(iPlaybackTimebase);
   1189     uint32 starttime = 0;
   1190     bool overflow = 0;
   1191     iPlaybackClock.SetStartTime32(starttime, PVMF_MEDIA_CLOCK_MSEC, overflow);
   1192     iPlaybackClock.ConstructMediaClockNotificationsInterface(iClockNotificationsInf, *this,
   1193             iCurrCallbackTimerLatency);
   1194 
   1195     // Initialize the OSCL timer for polling checks
   1196     iPollingCheckTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, ("playerengine_pollingcheck"));
   1197     iPollingCheckTimer->SetObserver(this);
   1198     iPollingCheckTimer->SetFrequency(10);  // 100 ms resolution
   1199 
   1200     iWatchDogTimer = OSCL_NEW(PVPlayerWatchdogTimer, (this));
   1201 
   1202     PVPlayerRegistryPopulator::Populate(iPlayerNodeRegistry, iPlayerRecognizerRegistry);
   1203 
   1204     return;
   1205 }
   1206 
   1207 
   1208 void PVPlayerEngine::Run()
   1209 {
   1210     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() In"));
   1211     int32 leavecode = 0;
   1212 
   1213     /* Engine AO will execute commands in the following sequence
   1214      * 1) If Engine state is Resetting, which will happen when Engine does ErrorHandling,
   1215      * processing Reset or CancelAllCommands
   1216      * issued by the app, engine will not try to execute any other command during this state.
   1217      * 2) If Engine is not in Resetting state then it will process commands in the following order, which ever is true:
   1218      *    (i) If Engine needs to do Error handling because of some error from Source Node or Datapath.
   1219      *    Either start error handling or complete it.
   1220      *    (ii) If Engine has Reset or CancelAllCommands in CurrentCommandQueue,
   1221      *    engine will do CommandComplete for the CurrentCommand.
   1222      *    (iii) If Engine has Prepare in CurrentCommandQueue, engine will call DoPrepare again
   1223      *    as a part of track selection logic
   1224      *    (iv) If Engine has CancelAllCommands or CancelAcquireLicense in Pending CommandQueue,
   1225      *    engine will start Cancel commands.
   1226      *    (v) Go for Rollover if in Init State and Roll-over is ongoing.
   1227      *    (vi) Process which ever command is pushed in Pending queue.
   1228      * Engine will process any one of the command as listed above in the same order.
   1229      * Every time engine AO is scheduled, engine will go through
   1230      * these steps.
   1231      */
   1232 
   1233     if (iState == PVP_ENGINE_STATE_RESETTING)
   1234     {
   1235         //this means error handling, reset or cancelall is still in progress
   1236         //pls note that the state will be set to idle
   1237         //in either HandleSourceNodeReset or HandleDataPathReset
   1238         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   1239                         (0, "PVPlayerEngine::Run() Return engine in resetting state, No processing until engine is in Idle state"));
   1240         return;
   1241     }
   1242 
   1243     /* Check if ErrorHandling request was made */
   1244     if (!iPendingCmds.empty())
   1245     {
   1246         switch (iPendingCmds.top().GetCmdType())
   1247         {
   1248             case PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE:
   1249             case PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT:
   1250             case PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE:
   1251             case PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE:
   1252             case PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME:
   1253             case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE:
   1254             case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE:
   1255             case PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP:
   1256             case PVP_ENGINE_COMMAND_ERROR_HANDLING_CANCEL_ALL_COMMANDS:
   1257             case PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL:
   1258             {
   1259                 // go in error handling right away
   1260                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing Error Handling request"));
   1261                 PVMFStatus retVal = DoErrorHandling();
   1262                 if (retVal == PVMFSuccess)
   1263                 {
   1264                     iPendingCmds.pop();
   1265                     RunIfNotReady(); // schedule the engine AO to process other commands in queue if any.
   1266                 }
   1267                 return;
   1268             }
   1269 
   1270             default:
   1271                 break;
   1272         }
   1273     }
   1274 
   1275     // if current command being processed is reset or cancelAll and
   1276     // Player engine state is idle then remove the data source
   1277     // and do reset/cancelAll command complete
   1278     // OR
   1279     // if current command being processed is prepare, need to call
   1280     // DoPrepare again because of track selection
   1281     if (!iCurrentCmd.empty())
   1282     {
   1283         if ((iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_RESET) ||
   1284                 (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_COMMAND) ||
   1285                 (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS))
   1286         {
   1287             if (iState != PVP_ENGINE_STATE_IDLE)
   1288             {
   1289                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Engine not in Idle State, asserting"));
   1290                 OSCL_ASSERT(false);
   1291             }
   1292             // First destroy all datapaths.
   1293             DoRemoveAllSinks();
   1294             // now remove the source node.
   1295             if (iDataSource)
   1296             {
   1297                 RemoveDataSourceSync(*iDataSource);
   1298             }
   1299 
   1300             EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFSuccess);
   1301         }
   1302         else if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_PREPARE)
   1303         {
   1304             PVMFStatus cmdstatus = DoPrepare(iCurrentCmd[0]);
   1305 
   1306             if (cmdstatus != PVMFSuccess && cmdstatus != PVMFPending)
   1307             {
   1308                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Command failed CmdId %d Status %d",
   1309                                 iCurrentCmd[0].GetCmdId(), cmdstatus));
   1310                 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), cmdstatus);
   1311             }
   1312         }
   1313     }
   1314 
   1315     /* Check if Cancel()/CancelAll()/CancelAcquireLicense request was made */
   1316     if (!iPendingCmds.empty())
   1317     {
   1318         if (iPendingCmds.top().GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_COMMAND)
   1319         {
   1320             // Process it right away
   1321             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing Cancel() request"));
   1322             PVPlayerEngineCommand cmd(iPendingCmds.top());
   1323             iPendingCmds.pop();
   1324             if ((!iCurrentCmd.empty()) && (iCurrentCmd[0].GetCmdId() == cmd.GetParam(0).int32_value))
   1325             {
   1326                 // We need to cancel the ongoing command. In this case issue cancelAll
   1327                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1328                                 (0, "PVPlayerEngine::Run: Command to Cancel is ongoing so issue CancelAll"));
   1329                 DoCancelAllCommands(cmd);
   1330             }
   1331             else
   1332             {
   1333                 // The command to be cancelled is in the pending queue
   1334                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1335                                 (0, "PVPlayerEngine::Run: Command to Cancel is pending so just Cancel"));
   1336                 DoCancelCommand(cmd);
   1337             }
   1338             return;
   1339         }
   1340         else if (iPendingCmds.top().GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS)
   1341         {
   1342             // Process it right away
   1343             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing CancelAll() request"));
   1344             PVPlayerEngineCommand cmd(iPendingCmds.top());
   1345             iPendingCmds.pop();
   1346             DoCancelAllCommands(cmd);
   1347             return;
   1348         }
   1349         else if (iPendingCmds.top().GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE)
   1350         {
   1351             // Process it right away
   1352             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing CancelAcquireLicesense() request"));
   1353             PVPlayerEngineCommand cmd(iPendingCmds.top());
   1354             iPendingCmds.pop();
   1355             DoCancelAcquireLicense(cmd);
   1356             return;
   1357         }
   1358     }
   1359 
   1360     if (iRollOverState == RollOverStateStart)
   1361     {
   1362         if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_INIT)
   1363         {
   1364             //implies that we are doing a source rollover
   1365             PVMFStatus status =
   1366                 DoSourceNodeRollOver(iCurrentCmd[0].iCmdId,
   1367                                      iCurrentCmd[0].iContextData);
   1368 
   1369             if (status != PVMFPending)
   1370             {
   1371                 if (CheckForSourceRollOver())
   1372                 {
   1373                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() DoSourceNodeRollOver Failed, alternate source node for rollover is available"));
   1374                     RunIfNotReady();
   1375                     return;
   1376                 }
   1377                 // roll over failed
   1378                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() DoSourceNodeRollOver Failed, go in error handling"));
   1379                 bool ehPending = CheckForPendingErrorHandlingCmd();
   1380                 if (ehPending)
   1381                 {
   1382                     // there should be no error handling queued.
   1383                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Already EH pending, should never happen"));
   1384                     return;
   1385                 }
   1386                 // go in error handling
   1387                 iCommandCompleteStatusInErrorHandling = status;
   1388                 iCommandCompleteErrMsgInErrorHandling = NULL;
   1389                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   1390                 iRollOverState = RollOverStateIdle;
   1391                 return;
   1392             }
   1393             else
   1394             {
   1395                 iRollOverState = RollOverStateInProgress;
   1396             }
   1397         }
   1398         else
   1399         {
   1400             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Source Roll Over In Progress But Incorrect Engine Cmd"));
   1401             EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFErrInvalidState);
   1402         }
   1403         return;
   1404     }
   1405 
   1406     if (iRollOverState == RollOverStateInProgress)
   1407     {
   1408         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RunL() Source Roll Over In Progress "));
   1409         return;
   1410     }
   1411 
   1412     // Handle other requests normally
   1413     if (!iPendingCmds.empty() && iCurrentCmd.empty())
   1414     {
   1415         // Retrieve the first pending command from queue
   1416         PVPlayerEngineCommand cmd(iPendingCmds.top());
   1417         iPendingCmds.pop();
   1418 
   1419         // Put in on the current command queue
   1420         leavecode = 0;
   1421         OSCL_TRY(leavecode, iCurrentCmd.push_front(cmd));
   1422         OSCL_FIRST_CATCH_ANY(leavecode,
   1423                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Command could not be pushed onto iCurrentCmd vector"));
   1424                              EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), PVMFErrNoMemory);
   1425                              return;);
   1426 
   1427         // Process the command according to the cmd type
   1428         PVMFStatus cmdstatus = PVMFSuccess;
   1429         bool ootsync = false;
   1430         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing command with type=%d", cmd.GetCmdType()));
   1431         switch (cmd.GetCmdType())
   1432         {
   1433             case PVP_ENGINE_COMMAND_GET_SDK_INFO:
   1434                 cmdstatus = DoGetSDKInfo(cmd);
   1435                 break;
   1436 
   1437             case PVP_ENGINE_COMMAND_GET_SDK_MODULE_INFO:
   1438                 // GetSDKModuleInfo is currently not supported
   1439                 cmdstatus = PVMFErrNotSupported;
   1440                 break;
   1441 
   1442             case PVP_ENGINE_COMMAND_SET_LOG_APPENDER:
   1443                 cmdstatus = DoSetLogAppender(cmd);
   1444                 break;
   1445 
   1446             case PVP_ENGINE_COMMAND_REMOVE_LOG_APPENDER:
   1447                 cmdstatus = DoRemoveLogAppender(cmd);
   1448                 break;
   1449 
   1450             case PVP_ENGINE_COMMAND_SET_LOG_LEVEL:
   1451                 cmdstatus = DoSetLogLevel(cmd);
   1452                 break;
   1453 
   1454             case PVP_ENGINE_COMMAND_GET_LOG_LEVEL:
   1455                 cmdstatus = DoGetLogLevel(cmd);
   1456                 break;
   1457 
   1458             case PVP_ENGINE_COMMAND_QUERY_UUID:
   1459                 cmdstatus = DoQueryUUID(cmd);;
   1460                 break;
   1461 
   1462             case PVP_ENGINE_COMMAND_QUERY_INTERFACE:
   1463                 cmdstatus = DoQueryInterface(cmd);
   1464                 break;
   1465 
   1466             case PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE:
   1467                 cmdstatus = DoGetPVPlayerState(cmd, false);
   1468                 break;
   1469 
   1470             case PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE_OOTSYNC:
   1471                 ootsync = true;
   1472                 cmdstatus = DoGetPVPlayerState(cmd, true);
   1473                 break;
   1474 
   1475             case PVP_ENGINE_COMMAND_ADD_DATA_SOURCE:
   1476                 cmdstatus = DoAddDataSource(cmd);
   1477                 break;
   1478 
   1479             case PVP_ENGINE_COMMAND_INIT:
   1480                 cmdstatus = DoInit(cmd);
   1481                 break;
   1482 
   1483             case PVP_ENGINE_COMMAND_GET_METADATA_KEY:
   1484                 cmdstatus = DoGetMetadataKey(cmd);
   1485                 break;
   1486 
   1487             case PVP_ENGINE_COMMAND_GET_METADATA_VALUE:
   1488                 cmdstatus = DoGetMetadataValue(cmd);
   1489                 break;
   1490 
   1491             case PVP_ENGINE_COMMAND_RELEASE_METADATA_VALUE:
   1492                 cmdstatus = DoReleaseMetadataValues(cmd);
   1493                 break;
   1494 
   1495             case PVP_ENGINE_COMMAND_ADD_DATA_SINK:
   1496                 cmdstatus = DoAddDataSink(cmd);
   1497                 break;
   1498 
   1499             case PVP_ENGINE_COMMAND_GET_CURRENT_POSITION:
   1500                 cmdstatus = DoGetCurrentPosition(cmd, false);
   1501                 break;
   1502 
   1503             case PVP_ENGINE_COMMAND_GET_CURRENT_POSITION_OOTSYNC:
   1504                 ootsync = true;
   1505                 cmdstatus = DoGetCurrentPosition(cmd, true);
   1506                 break;
   1507 
   1508             case PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE:
   1509                 cmdstatus = DoSetPlaybackRange(cmd);
   1510                 break;
   1511 
   1512             case PVP_ENGINE_COMMAND_GET_PLAYBACK_RANGE:
   1513                 cmdstatus = DoGetPlaybackRange(cmd);
   1514                 break;
   1515 
   1516             case PVP_ENGINE_COMMAND_SET_PLAYBACK_RATE:
   1517                 cmdstatus = DoSetPlaybackRate(cmd);
   1518                 break;
   1519 
   1520             case PVP_ENGINE_COMMAND_GET_PLAYBACK_RATE:
   1521                 cmdstatus = DoGetPlaybackRate(cmd);
   1522                 break;
   1523 
   1524             case PVP_ENGINE_COMMAND_GET_PLAYBACK_MINMAX_RATE:
   1525                 cmdstatus = DoGetPlaybackMinMaxRate(cmd);
   1526                 break;
   1527 
   1528             case PVP_ENGINE_COMMAND_PREPARE:
   1529                 cmdstatus = DoPrepare(cmd);
   1530                 break;
   1531 
   1532             case PVP_ENGINE_COMMAND_START:
   1533                 cmdstatus = DoStart(cmd);
   1534                 break;
   1535 
   1536             case PVP_ENGINE_COMMAND_PAUSE:
   1537             case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP:
   1538             case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED:
   1539                 cmdstatus = DoPause(cmd);
   1540                 break;
   1541 
   1542             case PVP_ENGINE_COMMAND_RESUME:
   1543                 cmdstatus = DoResume(cmd);
   1544                 break;
   1545 
   1546             case PVP_ENGINE_COMMAND_STOP:
   1547                 cmdstatus = DoStop(cmd);
   1548                 break;
   1549 
   1550             case PVP_ENGINE_COMMAND_REMOVE_DATA_SINK:
   1551                 cmdstatus = DoRemoveDataSink(cmd);
   1552                 break;
   1553 
   1554             case PVP_ENGINE_COMMAND_RESET:
   1555                 cmdstatus = DoReset(cmd);
   1556                 break;
   1557 
   1558             case PVP_ENGINE_COMMAND_REMOVE_DATA_SOURCE:
   1559                 cmdstatus = DoRemoveDataSource(cmd);
   1560                 break;
   1561 
   1562             case PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS:
   1563                 cmdstatus = DoCapConfigSetParameters(cmd, false);
   1564                 break;
   1565 
   1566             case PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS_OOTSYNC:
   1567                 ootsync = true;
   1568                 cmdstatus = DoCapConfigSetParameters(cmd, true);
   1569                 break;
   1570 
   1571             case PVP_ENGINE_COMMAND_CAPCONFIG_GET_PARAMETERS_OOTSYNC:
   1572                 ootsync = true;
   1573                 cmdstatus = DoGetParametersSync(cmd);
   1574                 break;
   1575 
   1576             case PVP_ENGINE_COMMAND_CAPCONFIG_RELEASE_PARAMETERS_OOTSYNC:
   1577                 ootsync = true;
   1578                 cmdstatus = DoReleaseParametersSync(cmd);
   1579                 break;
   1580 
   1581             case PVP_ENGINE_COMMAND_CAPCONFIG_VERIFY_PARAMETERS_OOTSYNC:
   1582                 ootsync = true;
   1583                 cmdstatus = DoVerifyParametersSync(cmd);
   1584                 break;
   1585 
   1586             case PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR:
   1587             case PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR:
   1588                 cmdstatus = DoAcquireLicense(cmd);
   1589                 break;
   1590 
   1591             case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW:
   1592                 cmdstatus = DoSourceUnderflowAutoPause(cmd);
   1593                 break;
   1594 
   1595             case PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY:
   1596                 cmdstatus = DoSourceDataReadyAutoResume(cmd);
   1597                 break;
   1598 
   1599             case PVP_ENGINE_COMMAND_CAPCONFIG_SET_OBSERVER_OOTSYNC:
   1600                 ootsync = true;
   1601                 cmdstatus = DoSetObserverSync(cmd);
   1602                 break;
   1603 
   1604             case PVP_ENGINE_COMMAND_GET_LICENSE_STATUS_OOTSYNC:
   1605                 ootsync = true;
   1606                 cmdstatus = DoGetLicenseStatusSync(cmd);
   1607                 break;
   1608 
   1609             case PVP_ENGINE_COMMAND_CANCEL_COMMAND:
   1610                 // Cancel() should not be handled here
   1611                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() CancelCommand should be not handled in here. Return Failure"));
   1612                 cmdstatus = PVMFFailure;
   1613                 break;
   1614 
   1615             case PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS:
   1616                 // CancelAll() should not be handled here
   1617                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() CancelAllCommands should be not handled in here. Return Failure"));
   1618                 cmdstatus = PVMFFailure;
   1619                 break;
   1620 
   1621             default:
   1622                 // Just handle as "not supported"
   1623                 cmdstatus = PVMFErrNotSupported;
   1624                 break;
   1625         }
   1626 
   1627         if (ootsync)
   1628         {
   1629             OOTSyncCommandComplete(cmd, cmdstatus);
   1630             // Empty out the current cmd vector and set active if there are other pending commands
   1631             iCurrentCmd.erase(iCurrentCmd.begin());
   1632             if (!iPendingCmds.empty())
   1633             {
   1634                 RunIfNotReady();
   1635             }
   1636         }
   1637         else if (cmdstatus != PVMFSuccess && cmdstatus != PVMFPending)
   1638         {
   1639             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Command failed CmdId %d Status %d",
   1640                             cmd.GetCmdId(), cmdstatus));
   1641             EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), cmdstatus);
   1642         }
   1643     }
   1644 
   1645     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Out"));
   1646 }
   1647 
   1648 bool PVPlayerEngine::FindNodeTypeByNode(PVMFNodeInterface* aUnknownNode, PVPlayerNodeType& aNodeType, int32& aDatapathListIndex)
   1649 {
   1650     if (aUnknownNode == NULL)
   1651     {
   1652         // Cannot check with node pointer being NULL
   1653         // Might bring up false positives
   1654         aNodeType = PVP_NODETYPE_UNKNOWN;
   1655         aDatapathListIndex = -1;
   1656         return false;
   1657     }
   1658 
   1659     // Go through each engine datapath and find whether
   1660     // the specified node is a dec node or sink node
   1661     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   1662     {
   1663         if (iDatapathList[i].iDecNode == aUnknownNode)
   1664         {
   1665             aNodeType = PVP_NODETYPE_DECODER;
   1666             aDatapathListIndex = i;
   1667             return true;
   1668         }
   1669         else if (iDatapathList[i].iSinkNode == aUnknownNode)
   1670         {
   1671             aNodeType = PVP_NODETYPE_SINK;
   1672             aDatapathListIndex = i;
   1673             return true;
   1674         }
   1675     }
   1676 
   1677     // Could not determine the types
   1678     aNodeType = PVP_NODETYPE_UNKNOWN;
   1679     aDatapathListIndex = -1;
   1680     return false;
   1681 }
   1682 
   1683 bool PVPlayerEngine::FindTrackForDatapathUsingMimeString(bool& aVideoTrack, bool& aAudioTrack, bool& aTextTrack, PVPlayerEngineDatapath* aDatapath)
   1684 {
   1685     if (aDatapath->iTrackInfo)
   1686     {
   1687         char* mimeString = aDatapath->iTrackInfo->getTrackMimeType().get_str();
   1688 
   1689         if ((pv_mime_strcmp(mimeString, PVMF_MIME_YUV420) == 0) ||
   1690                 (pv_mime_strcmp(mimeString, PVMF_MIME_YUV422) == 0) ||
   1691                 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB8) == 0) ||
   1692                 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB12) == 0) ||
   1693                 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB16) == 0) ||
   1694                 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB24) == 0) ||
   1695                 (pv_mime_strcmp(mimeString, PVMF_MIME_M4V) == 0) ||
   1696                 (pv_mime_strcmp(mimeString, PVMF_MIME_H2631998) == 0) ||
   1697                 (pv_mime_strcmp(mimeString, PVMF_MIME_H2632000) == 0) ||
   1698                 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_RAW) == 0) ||
   1699                 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_MP4) == 0) ||
   1700                 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO) == 0) ||
   1701                 (pv_mime_strcmp(mimeString, PVMF_MIME_WMV) == 0) ||
   1702                 (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_VIDEO) == 0))
   1703         {
   1704             aVideoTrack = true;
   1705             aAudioTrack = false;
   1706             aTextTrack = false;
   1707             return true;
   1708         }
   1709         else if (pv_mime_strcmp(mimeString, PVMF_MIME_3GPP_TIMEDTEXT) == 0)
   1710         {
   1711             aVideoTrack = false;
   1712             aAudioTrack = false;
   1713             aTextTrack = true;
   1714             return true;
   1715         }
   1716         else if ((pv_mime_strcmp(mimeString, PVMF_MIME_PCM) == 0) ||
   1717                  (pv_mime_strcmp(mimeString, PVMF_MIME_PCM8) == 0) ||
   1718                  (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16) == 0) ||
   1719                  (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16_BE) == 0) ||
   1720                  (pv_mime_strcmp(mimeString, PVMF_MIME_ULAW) == 0) ||
   1721                  (pv_mime_strcmp(mimeString, PVMF_MIME_ALAW) == 0) ||
   1722                  (pv_mime_strcmp(mimeString, PVMF_MIME_AMR) == 0) ||
   1723                  (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB) == 0) ||
   1724                  (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IETF) == 0) ||
   1725                  (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB_IETF) == 0) ||
   1726                  (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IF2) == 0) ||
   1727                  (pv_mime_strcmp(mimeString, PVMF_MIME_EVRC) == 0) ||
   1728                  (pv_mime_strcmp(mimeString, PVMF_MIME_MP3) == 0) ||
   1729                  (pv_mime_strcmp(mimeString, PVMF_MIME_ADIF) == 0) ||
   1730                  (pv_mime_strcmp(mimeString, PVMF_MIME_ADTS) == 0) ||
   1731                  (pv_mime_strcmp(mimeString, PVMF_MIME_LATM) == 0) ||
   1732                  (pv_mime_strcmp(mimeString, PVMF_MIME_MPEG4_AUDIO) == 0) ||
   1733                  (pv_mime_strcmp(mimeString, PVMF_MIME_G723) == 0) ||
   1734                  (pv_mime_strcmp(mimeString, PVMF_MIME_G726) == 0) ||
   1735                  (pv_mime_strcmp(mimeString, PVMF_MIME_WMA) == 0) ||
   1736                  (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_AMR) == 0) ||
   1737                  (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_AUDIO) == 0) ||
   1738                  (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_MPEG4_AUDIO) == 0) ||
   1739                  (pv_mime_strcmp(mimeString, PVMF_MIME_3640) == 0))
   1740         {
   1741             aVideoTrack = false;
   1742             aAudioTrack = true;
   1743             aTextTrack = false;
   1744             return true;
   1745         }
   1746         else
   1747         {
   1748             aVideoTrack = false;
   1749             aAudioTrack = false;
   1750             aTextTrack = false;
   1751             return false;
   1752         }
   1753     }
   1754 
   1755     aVideoTrack = false;
   1756     aAudioTrack = false;
   1757     aTextTrack = false;
   1758     return false;
   1759 }
   1760 
   1761 bool PVPlayerEngine::FindDatapathForTrackUsingMimeString(bool aVideoTrack, bool aAudioTrack, bool aTextTrack, int32& aDatapathListIndex)
   1762 {
   1763     for (uint32 i = 0; i < iDatapathList.size(); i++)
   1764     {
   1765         if (iDatapathList[i].iTrackInfo)
   1766         {
   1767             char* mimeString = iDatapathList[i].iTrackInfo->getTrackMimeType().get_str();
   1768             if (aVideoTrack)
   1769             {
   1770                 // find a datapath using the mime string for Video track
   1771                 if ((pv_mime_strcmp(mimeString, PVMF_MIME_YUV420) == 0) ||
   1772                         (pv_mime_strcmp(mimeString, PVMF_MIME_YUV422) == 0) ||
   1773                         (pv_mime_strcmp(mimeString, PVMF_MIME_RGB8) == 0) ||
   1774                         (pv_mime_strcmp(mimeString, PVMF_MIME_RGB12) == 0) ||
   1775                         (pv_mime_strcmp(mimeString, PVMF_MIME_RGB16) == 0) ||
   1776                         (pv_mime_strcmp(mimeString, PVMF_MIME_RGB24) == 0) ||
   1777                         (pv_mime_strcmp(mimeString, PVMF_MIME_M4V) == 0) ||
   1778                         (pv_mime_strcmp(mimeString, PVMF_MIME_H2631998) == 0) ||
   1779                         (pv_mime_strcmp(mimeString, PVMF_MIME_H2632000) == 0) ||
   1780                         (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_RAW) == 0) ||
   1781                         (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_MP4) == 0) ||
   1782                         (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO) == 0) ||
   1783                         (pv_mime_strcmp(mimeString, PVMF_MIME_WMV) == 0) ||
   1784                         (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_VIDEO) == 0))
   1785                 {
   1786                     aDatapathListIndex = i;
   1787                     return true;
   1788                 }
   1789             }
   1790             else if (aAudioTrack)
   1791             {
   1792                 // find a datapath using the mime string for Audio track
   1793                 if ((pv_mime_strcmp(mimeString, PVMF_MIME_PCM) == 0) ||
   1794                         (pv_mime_strcmp(mimeString, PVMF_MIME_PCM8) == 0) ||
   1795                         (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16) == 0) ||
   1796                         (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16_BE) == 0) ||
   1797                         (pv_mime_strcmp(mimeString, PVMF_MIME_ULAW) == 0) ||
   1798                         (pv_mime_strcmp(mimeString, PVMF_MIME_ALAW) == 0) ||
   1799                         (pv_mime_strcmp(mimeString, PVMF_MIME_AMR) == 0) ||
   1800                         (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB) == 0) ||
   1801                         (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IETF) == 0) ||
   1802                         (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB_IETF) == 0) ||
   1803                         (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IF2) == 0) ||
   1804                         (pv_mime_strcmp(mimeString, PVMF_MIME_EVRC) == 0) ||
   1805                         (pv_mime_strcmp(mimeString, PVMF_MIME_MP3) == 0) ||
   1806                         (pv_mime_strcmp(mimeString, PVMF_MIME_ADIF) == 0) ||
   1807                         (pv_mime_strcmp(mimeString, PVMF_MIME_ADTS) == 0) ||
   1808                         (pv_mime_strcmp(mimeString, PVMF_MIME_LATM) == 0) ||
   1809                         (pv_mime_strcmp(mimeString, PVMF_MIME_MPEG4_AUDIO) == 0) ||
   1810                         (pv_mime_strcmp(mimeString, PVMF_MIME_G723) == 0) ||
   1811                         (pv_mime_strcmp(mimeString, PVMF_MIME_G726) == 0) ||
   1812                         (pv_mime_strcmp(mimeString, PVMF_MIME_WMA) == 0) ||
   1813                         (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_AMR) == 0) ||
   1814                         (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_AUDIO) == 0) ||
   1815                         (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_MPEG4_AUDIO) == 0) ||
   1816                         (pv_mime_strcmp(mimeString, PVMF_MIME_3640) == 0))
   1817                 {
   1818                     aDatapathListIndex = i;
   1819                     return true;
   1820                 }
   1821             }
   1822             else if (aTextTrack)
   1823             {
   1824                 // find a datapath using the mime string for Text track
   1825                 if (pv_mime_strcmp(mimeString, PVMF_MIME_3GPP_TIMEDTEXT) == 0)
   1826                 {
   1827                     aDatapathListIndex = i;
   1828                     return true;
   1829                 }
   1830             }
   1831             else
   1832             {
   1833                 // Unknown track
   1834                 aDatapathListIndex = -1;
   1835                 return false;
   1836             }
   1837         }
   1838     }
   1839 
   1840     // Unknown track
   1841     aDatapathListIndex = -1;
   1842     return false;
   1843 }
   1844 
   1845 
   1846 void PVPlayerEngine::NodeCommandCompleted(const PVMFCmdResp& aResponse)
   1847 {
   1848     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() In"));
   1849 
   1850     int32 leavecode = 0;
   1851 
   1852     // Check if a cancel command completed
   1853     uint32* context_uint32 = (uint32*)(aResponse.GetContext());
   1854     if (context_uint32 == &iNumberCancelCmdPending)
   1855     {
   1856         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Cancel in node completed for cancel command. Pending %d", iNumberCancelCmdPending));
   1857         --iNumberCancelCmdPending;
   1858 
   1859         // If cmd to cancel was GetMetadataKeys() or GetMetadataValues() and if these commands return with
   1860         // success then first release the memory for the node which return with success.
   1861         if (iCmdToCancel[0].GetCmdType() == PVP_ENGINE_COMMAND_GET_METADATA_KEY &&
   1862                 aResponse.GetCmdStatus() == PVMFSuccess)
   1863         {
   1864             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1865                             (0, "PVPlayerEngine::NodeCommandCompleted() Cancel in node completed for GetMetadataKeys with success, release memory."));
   1866             // Release the memory allocated for the metadata keys
   1867             uint32 numkeysadded = iGetMetadataKeysParam.iKeyList->size() - iGetMetadataKeysParam.iNumKeyEntriesInList;
   1868             uint32 start = iGetMetadataKeysParam.iNumKeyEntriesInList;
   1869             uint32 end = iGetMetadataKeysParam.iNumKeyEntriesInList + numkeysadded - 1;
   1870 
   1871             PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iInterface;
   1872             OSCL_ASSERT(mdif != NULL);
   1873             mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), start, end);
   1874         }
   1875         else if (iCmdToCancel[0].GetCmdType() == PVP_ENGINE_COMMAND_GET_METADATA_VALUE &&
   1876                  aResponse.GetCmdStatus() == PVMFSuccess)
   1877         {
   1878             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1879                             (0, "PVPlayerEngine::NodeCommandCompleted() Cancel in node completed for GetMetadataValue with success, release memory."));
   1880             // Release the memory allocated for the metadata values
   1881             uint32 numkeysadded = iGetMetadataValuesParam.iKeyList->size() - iGetMetadataValuesParam.iNumValueEntriesInList;
   1882             uint32 start = iGetMetadataValuesParam.iNumValueEntriesInList;
   1883             uint32 end = iGetMetadataValuesParam.iNumValueEntriesInList + numkeysadded - 1;
   1884 
   1885             PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iInterface;
   1886             OSCL_ASSERT(mdif != NULL);
   1887             mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), start, end);
   1888 
   1889             iReleaseMetadataValuesPending = false;
   1890         }
   1891 
   1892         if (iNumberCancelCmdPending == 0)
   1893         {
   1894             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Cancelling of all node/datapath commands complete, now reset all nodes"));
   1895             // Clear the CancelCmd queue as the cmd has been cancelled.
   1896             iCmdToCancel.clear();
   1897 
   1898             RemoveDatapathContextFromList(); // empty left over contexts from cancelled datapath commands
   1899             // Now reset the source node
   1900             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   1901 
   1902             PVMFCommandId cmdid = -1;
   1903             int32 leavecode = 0;
   1904             OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   1905             OSCL_FIRST_CATCH_ANY(leavecode,
   1906 
   1907                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Reset on iSourceNode did a leave!"));
   1908                                  FreeEngineContext(context);
   1909                                  OSCL_ASSERT(false);
   1910                                  return);
   1911 
   1912             SetEngineState(PVP_ENGINE_STATE_RESETTING);
   1913         }
   1914         return;
   1915     }
   1916 
   1917     PVPlayerEngineContext* nodecontext = (PVPlayerEngineContext*)(aResponse.GetContext());
   1918     OSCL_ASSERT(nodecontext);
   1919 
   1920     // Ignore other node completion if cancelling
   1921     if (!iCmdToCancel.empty() || (CheckForPendingErrorHandlingCmd() && aResponse.GetCmdStatus() == PVMFErrCancelled))
   1922     {
   1923         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Node command completion ignored due to cancel process, id=%d", aResponse.GetCmdId()));
   1924         // Remove the context from the list
   1925         FreeEngineContext(nodecontext);
   1926         return;
   1927     }
   1928 
   1929     // Process according to cmd type in the engine context data, node type, or engine state
   1930     if (nodecontext->iCmdType == PVP_CMD_SinkNodeSkipMediaData)
   1931     {
   1932         HandleSinkNodeSkipMediaData(*nodecontext, aResponse);
   1933     }
   1934     else if (nodecontext->iCmdType == PVP_CMD_SinkNodeSkipMediaDataDuringPlayback)
   1935     {
   1936         HandleSinkNodeSkipMediaDataDuringPlayback(*nodecontext, aResponse);
   1937     }
   1938     else if (nodecontext->iCmdType == PVP_CMD_SinkNodeAutoPause)
   1939     {
   1940         HandleSinkNodePause(*nodecontext, aResponse);
   1941     }
   1942     else if (nodecontext->iCmdType == PVP_CMD_SinkNodeAutoResume)
   1943     {
   1944         HandleSinkNodeResume(*nodecontext, aResponse);
   1945     }
   1946     else if (nodecontext->iCmdType == PVP_CMD_DecNodeReset)
   1947     {
   1948         HandleDecNodeReset(*nodecontext, aResponse);
   1949     }
   1950     else if (nodecontext->iCmdType == PVP_CMD_SinkNodeReset)
   1951     {
   1952         HandleSinkNodeReset(*nodecontext, aResponse);
   1953     }
   1954     else if (nodecontext->iCmdType == PVP_CMD_GetNodeMetadataKey)
   1955     {
   1956         // Ignore the command status since it does not matter and continue going through the metadata interface list
   1957 
   1958         // Determine the number of keys were added
   1959         uint32 numkeysadded = iGetMetadataKeysParam.iKeyList->size() - iGetMetadataKeysParam.iNumKeyEntriesInList;
   1960         if (numkeysadded > 0)
   1961         {
   1962             // Create an entry for the metadata key release list
   1963             PVPlayerEngineMetadataReleaseEntry releaseentry;
   1964             releaseentry.iMetadataIFListIndex = iGetMetadataKeysParam.iCurrentInterfaceIndex;
   1965             // Save the start and end indices into the key list for keys that this node added
   1966             releaseentry.iStartIndex = iGetMetadataKeysParam.iNumKeyEntriesInList;
   1967             releaseentry.iEndIndex = iGetMetadataKeysParam.iNumKeyEntriesInList + numkeysadded - 1;
   1968 
   1969             leavecode = 0;
   1970             OSCL_TRY(leavecode, iMetadataKeyReleaseList.push_back(releaseentry));
   1971             if (leavecode != 0)
   1972             {
   1973                 // An element could not be added to the release list vector
   1974                 // so notify completion of GetMetadataKey() command with memory failure
   1975                 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, PVMFErrNoMemory);
   1976 
   1977                 // Release the last requested keys
   1978                 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[releaseentry.iMetadataIFListIndex].iInterface;
   1979                 OSCL_ASSERT(mdif != NULL);
   1980                 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), releaseentry.iStartIndex, releaseentry.iEndIndex);
   1981 
   1982                 // Release the memory allocated for rest of the metadata keys
   1983                 while (iMetadataKeyReleaseList.empty() == false)
   1984                 {
   1985                     mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
   1986                     OSCL_ASSERT(mdif != NULL);
   1987                     mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
   1988                     iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
   1989                 }
   1990 
   1991                 // Remove the context from the list
   1992                 // Need to do this since we're calling return from here
   1993                 FreeEngineContext(nodecontext);
   1994                 return;
   1995             }
   1996 
   1997             // Update the variables tracking the key list
   1998             if (iGetMetadataKeysParam.iNumKeyEntriesToFill != -1)
   1999             {
   2000                 iGetMetadataKeysParam.iNumKeyEntriesToFill -= numkeysadded;
   2001             }
   2002             iGetMetadataKeysParam.iNumKeyEntriesInList += numkeysadded;
   2003         }
   2004 
   2005         // Update the interface index to the next one
   2006         ++iGetMetadataKeysParam.iCurrentInterfaceIndex;
   2007 
   2008         // Loop until GetNodeMetadataKeys() is called or command is completed
   2009         bool endloop = false;
   2010         while (endloop == false)
   2011         {
   2012             // Check if there is another metadata interface to check
   2013             if (iGetMetadataKeysParam.iCurrentInterfaceIndex < iMetadataIFList.size())
   2014             {
   2015                 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iInterface;
   2016                 OSCL_ASSERT(mdif != NULL);
   2017                 PVMFSessionId sessionid = iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iSessionId;
   2018 
   2019                 // Determine the number of keys available for the specified query key
   2020                 int32 numkeys = mdif->GetNumMetadataKeys(iGetMetadataKeysParam.iQueryKey);
   2021                 if (numkeys <= 0)
   2022                 {
   2023                     // Since there is no keys from this node, go to the next one
   2024                     ++iGetMetadataKeysParam.iCurrentInterfaceIndex;
   2025                     continue;
   2026                 }
   2027 
   2028                 // If more key entries can be added, retrieve from the node
   2029                 if (iGetMetadataKeysParam.iNumKeyEntriesToFill > 0 || iGetMetadataKeysParam.iNumKeyEntriesToFill == -1)
   2030                 {
   2031                     int32 leavecode = 0;
   2032                     PVMFCommandId cmdid = -1;
   2033                     PVPlayerEngineContext* newcontext = AllocateEngineContext(iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iEngineDatapath, iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iNode, NULL, nodecontext->iCmdId, nodecontext->iCmdContext, PVP_CMD_GetNodeMetadataKey);
   2034                     OSCL_TRY(leavecode, cmdid = mdif->GetNodeMetadataKeys(sessionid,
   2035                                                 *(iGetMetadataKeysParam.iKeyList),
   2036                                                 0,
   2037                                                 iGetMetadataKeysParam.iNumKeyEntriesToFill,
   2038                                                 iGetMetadataKeysParam.iQueryKey,
   2039                                                 (OsclAny*)newcontext));
   2040                     OSCL_FIRST_CATCH_ANY(leavecode,
   2041                                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() GetNodeMetadataKeys on a node did a leave!"));
   2042                                          FreeEngineContext(newcontext);
   2043                                          // Go to the next metadata IF in the list and continue
   2044                                          ++iGetMetadataKeysParam.iCurrentInterfaceIndex;
   2045                                          continue;);
   2046 
   2047                     // End the loop since GetNodeMetadataKeys() was called
   2048                     endloop = true;
   2049                 }
   2050                 else
   2051                 {
   2052                     // Retrieved the requested number of keys so notify completion of GetMetadataKey() command
   2053                     EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
   2054 
   2055                     // Release the memory allocated for the metadata keys
   2056                     while (iMetadataKeyReleaseList.empty() == false)
   2057                     {
   2058                         mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
   2059                         OSCL_ASSERT(mdif != NULL);
   2060                         mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
   2061                         iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
   2062                     }
   2063 
   2064                     // End the loop since finished command
   2065                     endloop = true;
   2066                 }
   2067             }
   2068             else
   2069             {
   2070                 // No more so notify completion of GetMetadataKey() command
   2071                 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
   2072 
   2073                 // Release the memory allocated for the metadata keys
   2074                 while (iMetadataKeyReleaseList.empty() == false)
   2075                 {
   2076                     PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
   2077                     OSCL_ASSERT(mdif != NULL);
   2078                     mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
   2079                     iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
   2080                 }
   2081 
   2082                 // End the loop since reached the end of the metadata IF list
   2083                 endloop = true;
   2084             }
   2085         }
   2086     }
   2087     else if (nodecontext->iCmdType == PVP_CMD_GetNodeMetadataValue)
   2088     {
   2089         // Ignore the command status since it does not matter and continue going through the metadata interface list
   2090 
   2091         // Determine the number of values were added
   2092         uint32 numvaluesadded = iGetMetadataValuesParam.iValueList->size() - iGetMetadataValuesParam.iNumValueEntriesInList;
   2093         if (numvaluesadded > 0)
   2094         {
   2095             // Create an entry for the metadata value release list
   2096             PVPlayerEngineMetadataReleaseEntry releaseentry;
   2097             releaseentry.iMetadataIFListIndex = iGetMetadataValuesParam.iCurrentInterfaceIndex;
   2098             // Save the start and end indices into the value list for values that this node added
   2099             releaseentry.iStartIndex = iGetMetadataValuesParam.iNumValueEntriesInList;
   2100             releaseentry.iEndIndex = iGetMetadataValuesParam.iNumValueEntriesInList + numvaluesadded - 1;
   2101 
   2102             leavecode = 0;
   2103             OSCL_TRY(leavecode, iMetadataValueReleaseList.push_back(releaseentry));
   2104             if (leavecode != 0)
   2105             {
   2106                 // An element could not be added to the release list vector
   2107                 // so notify completion of GetMetadataValue() command with memory failure
   2108                 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, PVMFErrNoMemory);
   2109 
   2110                 // Release the last requested values
   2111                 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[releaseentry.iMetadataIFListIndex].iInterface;
   2112                 OSCL_ASSERT(mdif != NULL);
   2113                 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), releaseentry.iStartIndex, releaseentry.iEndIndex);
   2114 
   2115                 // Release the memory allocated for rest of the metadata values
   2116                 while (iMetadataValueReleaseList.empty() == false)
   2117                 {
   2118                     mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
   2119                     OSCL_ASSERT(mdif != NULL);
   2120                     mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
   2121                     iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
   2122                 }
   2123 
   2124                 // Remove the context from the list
   2125                 // Need to do this since we're calling return from here
   2126                 FreeEngineContext(nodecontext);
   2127                 return;
   2128             }
   2129 
   2130             // Update the variables tracking the value list
   2131             if (iGetMetadataValuesParam.iNumValueEntriesToFill != -1)
   2132             {
   2133                 iGetMetadataValuesParam.iNumValueEntriesToFill -= numvaluesadded;
   2134             }
   2135             iGetMetadataValuesParam.iNumValueEntriesInList += numvaluesadded;
   2136         }
   2137 
   2138         // Update the interface index to the next one
   2139         ++iGetMetadataValuesParam.iCurrentInterfaceIndex;
   2140 
   2141         // Loop until GetNodeMetadataValues() is called or command is completed
   2142         bool endloop = false;
   2143         while (endloop == false)
   2144         {
   2145             // Check if there is another metadata interface to check
   2146             if (iGetMetadataValuesParam.iCurrentInterfaceIndex < iMetadataIFList.size())
   2147             {
   2148                 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iInterface;
   2149                 OSCL_ASSERT(mdif != NULL);
   2150                 PVMFSessionId sessionid = iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iSessionId;
   2151 
   2152                 // Determine the number of values available for the specified key list
   2153                 int32 numvalues = mdif->GetNumMetadataValues(*(iGetMetadataValuesParam.iKeyList));
   2154                 if (numvalues > 0)
   2155                 {
   2156                     // Add it to the total available
   2157                     *(iGetMetadataValuesParam.iNumAvailableValues) += numvalues;
   2158                 }
   2159                 else
   2160                 {
   2161                     // Since there is no values from this node, go to the next one
   2162                     ++iGetMetadataValuesParam.iCurrentInterfaceIndex;
   2163                     continue;
   2164                 }
   2165 
   2166                 // If more value entries can be added, retrieve from the node
   2167                 if (iGetMetadataValuesParam.iNumValueEntriesToFill > 0 || iGetMetadataValuesParam.iNumValueEntriesToFill == -1)
   2168                 {
   2169                     int32 leavecode = 0;
   2170                     PVMFCommandId cmdid = -1;
   2171                     PVPlayerEngineContext* newcontext = AllocateEngineContext(iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iEngineDatapath, iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iNode, NULL, nodecontext->iCmdId, nodecontext->iCmdContext, PVP_CMD_GetNodeMetadataValue);
   2172                     OSCL_TRY(leavecode, cmdid = mdif->GetNodeMetadataValues(sessionid,
   2173                                                 *(iGetMetadataValuesParam.iKeyList),
   2174                                                 *(iGetMetadataValuesParam.iValueList),
   2175                                                 0,
   2176                                                 iGetMetadataValuesParam.iNumValueEntriesToFill,
   2177                                                 (OsclAny*)newcontext));
   2178                     OSCL_FIRST_CATCH_ANY(leavecode,
   2179                                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() GetNodeMetadataValues on a node did a leave!"));
   2180                                          FreeEngineContext(newcontext);
   2181                                          // Go to the next metadata IF in the list and continue
   2182                                          ++iGetMetadataValuesParam.iCurrentInterfaceIndex;
   2183                                          continue;);
   2184 
   2185                     // End the loop since GetNodeMetadataValues() was called
   2186                     endloop = true;
   2187                 }
   2188                 else
   2189                 {
   2190                     // Retrieved requested number of values so notify completion of GetMetadataValue() command
   2191                     EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
   2192 
   2193                     if (iMetadataValuesCopiedInCallBack)
   2194                     {
   2195                         // Release the memory allocated for the metadata values
   2196                         while (iMetadataValueReleaseList.empty() == false)
   2197                         {
   2198                             mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
   2199                             OSCL_ASSERT(mdif != NULL);
   2200                             mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
   2201                             iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
   2202                         }
   2203                     }
   2204                     else
   2205                     {
   2206                         iReleaseMetadataValuesPending = true;
   2207                     }
   2208 
   2209                     // End the loop since finished command
   2210                     endloop = true;
   2211                 }
   2212             }
   2213             else
   2214             {
   2215                 // No more so notify completion of GetMetadataValue() command
   2216                 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
   2217 
   2218                 if (iMetadataValuesCopiedInCallBack)
   2219                 {
   2220                     // Release the memory allocated for the metadata values
   2221                     while (iMetadataValueReleaseList.empty() == false)
   2222                     {
   2223                         PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
   2224                         OSCL_ASSERT(mdif != NULL);
   2225                         mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
   2226                         iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
   2227                     }
   2228                 }
   2229                 else
   2230                 {
   2231                     iReleaseMetadataValuesPending = true;
   2232                 }
   2233 
   2234                 // End the loop since reached the end of the metadata IF list
   2235                 endloop = true;
   2236             }
   2237         }
   2238     }
   2239     else if (nodecontext->iNode == iSourceNode)
   2240     {
   2241         if (nodecontext->iCmdType == PVP_CMD_SourceNodeQueryDataSourcePositionDuringPlayback)
   2242         {
   2243             HandleSourceNodeQueryDataSourcePositionDuringPlayback(*nodecontext, aResponse);
   2244         }
   2245         else if (nodecontext->iCmdType == PVP_CMD_SourceNodeSetDataSourcePositionDuringPlayback)
   2246         {
   2247             HandleSourceNodeSetDataSourcePositionDuringPlayback(*nodecontext, aResponse);
   2248         }
   2249         else if (nodecontext->iCmdType == PVP_CMD_SourceNodeSetDataSourceDirection)
   2250         {
   2251             HandleSourceNodeSetDataSourceDirection(*nodecontext, aResponse);
   2252         }
   2253         else if (nodecontext->iCmdType == PVP_CMD_SourceNodeSetDataSourceRate)
   2254         {
   2255             HandleSourceNodeSetDataSourceRate(*nodecontext, aResponse);
   2256         }
   2257         else
   2258         {
   2259             switch (iState)
   2260             {
   2261                 case PVP_ENGINE_STATE_IDLE:
   2262                     switch (nodecontext->iCmdType)
   2263                     {
   2264                         case PVP_CMD_SourceNodeQueryInitIF:
   2265                             HandleSourceNodeQueryInitIF(*nodecontext, aResponse);
   2266                             break;
   2267 
   2268                         case PVP_CMD_SourceNodeQueryTrackSelIF:
   2269                             HandleSourceNodeQueryTrackSelIF(*nodecontext, aResponse);
   2270                             break;
   2271 
   2272                         case PVP_CMD_SourceNodeQueryTrackLevelInfoIF:
   2273                         case PVP_CMD_SourceNodeQueryPBCtrlIF:
   2274                         case PVP_CMD_SourceNodeQueryDirCtrlIF:
   2275                         case PVP_CMD_SourceNodeQueryMetadataIF:
   2276                         case PVP_CMD_SourceNodeQueryCapConfigIF:
   2277                         case PVP_CMD_SourceNodeQueryCPMLicenseIF:
   2278                         case PVP_CMD_SourceNodeQuerySrcNodeRegInitIF:
   2279                             HandleSourceNodeQueryInterfaceOptional(*nodecontext, aResponse);
   2280                             break;
   2281 
   2282                         case PVP_CMD_SourceNodeGetLicense:
   2283                             HandleSourceNodeGetLicense(*nodecontext, aResponse);
   2284                             break;
   2285 
   2286                         case PVP_CMD_SourceNodeCancelGetLicense:
   2287                             HandleSourceNodeCancelGetLicense(*nodecontext, aResponse);
   2288                             break;
   2289 
   2290                         default:
   2291                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_IDLE. Asserting"));
   2292                             OSCL_ASSERT(false);
   2293                             break;
   2294                     }
   2295                     break;
   2296 
   2297                 case PVP_ENGINE_STATE_INITIALIZED:
   2298                     switch (nodecontext->iCmdType)
   2299                     {
   2300                         case PVP_CMD_SourceNodeGetLicense:
   2301                             HandleSourceNodeGetLicense(*nodecontext, aResponse);
   2302                             break;
   2303                         default:
   2304                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_IDLE. Asserting"));
   2305                             OSCL_ASSERT(false);
   2306                             break;
   2307                     }
   2308                     break;
   2309 
   2310                 case PVP_ENGINE_STATE_INITIALIZING:
   2311                     switch (nodecontext->iCmdType)
   2312                     {
   2313                         case PVP_CMD_SourceNodeInit:
   2314                             HandleSourceNodeInit(*nodecontext, aResponse);
   2315                             break;
   2316 
   2317                         case PVP_CMD_SourceNodeGetDurationValue:
   2318                             HandleSourceNodeGetDurationValue(*nodecontext, aResponse);
   2319                             break;
   2320 
   2321                         default:
   2322                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_INITIALIZING. Asserting"));
   2323                             OSCL_ASSERT(false);
   2324                             break;
   2325                     }
   2326                     break;
   2327 
   2328                 case PVP_ENGINE_STATE_PREPARING:
   2329                     switch (nodecontext->iCmdType)
   2330                     {
   2331                         case PVP_CMD_SourceNodePrepare:
   2332                             HandleSourceNodePrepare(*nodecontext, aResponse);
   2333                             break;
   2334 
   2335                         case PVP_CMD_SourceNodeQueryDataSourcePosition:
   2336                             HandleSourceNodeQueryDataSourcePosition(*nodecontext, aResponse);
   2337                             break;
   2338 
   2339                         case PVP_CMD_SourceNodeSetDataSourcePosition:
   2340                             HandleSourceNodeSetDataSourcePosition(*nodecontext, aResponse);
   2341                             break;
   2342 
   2343                         case PVP_CMD_SourceNodeSetDataSourceDirection:
   2344                             //currently not allowed
   2345                             break;
   2346 
   2347                         case PVP_CMD_SourceNodeStart:
   2348                             HandleSourceNodeStart(*nodecontext, aResponse);
   2349                             break;
   2350 
   2351                         default:
   2352                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_PREPARING. Asserting"));
   2353                             OSCL_ASSERT(false);
   2354                             break;
   2355                     }
   2356                     break;
   2357 
   2358                 case PVP_ENGINE_STATE_PAUSING:
   2359                     HandleSourceNodePause(*nodecontext, aResponse);
   2360                     break;
   2361 
   2362                 case PVP_ENGINE_STATE_RESUMING:
   2363                     switch (nodecontext->iCmdType)
   2364                     {
   2365                         case PVP_CMD_SourceNodeQueryDataSourcePosition:
   2366                             HandleSourceNodeQueryDataSourcePosition(*nodecontext, aResponse);
   2367                             break;
   2368 
   2369                         case PVP_CMD_SourceNodeSetDataSourcePosition:
   2370                             HandleSourceNodeSetDataSourcePosition(*nodecontext, aResponse);
   2371                             break;
   2372 
   2373                         case PVP_CMD_SourceNodeSetDataSourceDirection:
   2374                             HandleSourceNodeSetDataSourceDirection(*nodecontext, aResponse);
   2375                             break;
   2376 
   2377                         case PVP_CMD_SourceNodeStart:
   2378                             HandleSourceNodeResume(*nodecontext, aResponse);
   2379                             break;
   2380 
   2381                         default:
   2382                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_RESUMING. Asserting"));
   2383                             OSCL_ASSERT(false);
   2384                             break;
   2385                     }
   2386                     break;
   2387 
   2388                 case PVP_ENGINE_STATE_STOPPING:
   2389                     HandleSourceNodeStop(*nodecontext, aResponse);
   2390                     break;
   2391 
   2392                 case PVP_ENGINE_STATE_RESETTING:
   2393                     HandleSourceNodeReset(*nodecontext, aResponse);
   2394                     break;
   2395 
   2396                 default:
   2397                     break;
   2398             }
   2399         }
   2400     }
   2401     else if (iState == PVP_ENGINE_STATE_PREPARING)
   2402     {
   2403         switch (nodecontext->iCmdType)
   2404         {
   2405             case PVP_CMD_SinkNodeQueryCapConfigIF:
   2406                 HandleSinkNodeQueryCapConfigIF(*nodecontext, aResponse);
   2407                 break;
   2408 
   2409             case PVP_CMD_SinkNodeInit:
   2410                 HandleSinkNodeInit(*nodecontext, aResponse);
   2411                 break;
   2412 
   2413             case PVP_CMD_DecNodeQueryCapConfigIF:
   2414                 HandleDecNodeQueryCapConfigIF(*nodecontext, aResponse);
   2415                 break;
   2416 
   2417             case PVP_CMD_DecNodeInit:
   2418                 HandleDecNodeInit(*nodecontext, aResponse);
   2419                 break;
   2420 
   2421             case PVP_CMD_SinkNodeDecNodeReset:
   2422                 HandleSinkNodeDecNodeReset(*nodecontext, aResponse);
   2423                 break;
   2424 
   2425             case PVP_CMD_SinkNodeQuerySyncCtrlIF:
   2426             case PVP_CMD_SinkNodeQueryMetadataIF:
   2427                 HandleSinkNodeQueryInterfaceOptional(*nodecontext, aResponse);
   2428                 break;
   2429 
   2430             case PVP_CMD_DecNodeQueryMetadataIF:
   2431                 HandleDecNodeQueryInterfaceOptional(*nodecontext, aResponse);
   2432                 break;
   2433 
   2434             default:
   2435                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid node command type in PVP_ENGINE_STATE_PREPARING. Asserting"));
   2436                 OSCL_ASSERT(false);
   2437                 break;
   2438         }
   2439     }
   2440     else
   2441     {
   2442         // Unknown node command completion. Assert
   2443         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Unknown node command completion"));
   2444         OSCL_ASSERT(false);
   2445     }
   2446 
   2447     // Remove the context from the list
   2448     FreeEngineContext(nodecontext);
   2449 
   2450     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Out"));
   2451 }
   2452 
   2453 
   2454 void PVPlayerEngine::HandleNodeInformationalEvent(const PVMFAsyncEvent& aEvent)
   2455 {
   2456     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeInformationalEvent() In"));
   2457 
   2458     PVMFNodeInterface* nodeorigin = (PVMFNodeInterface*)(aEvent.GetContext());
   2459 
   2460     PVPlayerNodeType nodetype = PVP_NODETYPE_UNKNOWN;
   2461     int32 datapathindex = -1;
   2462 
   2463     // Process the info event based on the node type reporting the event
   2464     if (nodeorigin == iSourceNode)
   2465     {
   2466         HandleSourceNodeInfoEvent(aEvent);
   2467     }
   2468     else if (FindNodeTypeByNode(nodeorigin, nodetype, datapathindex) == true)
   2469     {
   2470         if (nodetype == PVP_NODETYPE_SINK)
   2471         {
   2472             HandleSinkNodeInfoEvent(aEvent, datapathindex);
   2473         }
   2474         else if (nodetype == PVP_NODETYPE_DECODER)
   2475         {
   2476             HandleDecNodeInfoEvent(aEvent, datapathindex);
   2477         }
   2478         else
   2479         {
   2480             // Event from unknown node or component. Do nothing but log it
   2481             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleNodeInformationalEvent() Info event from unknown node type Event type 0x%x Context 0x%x Data 0x%x",
   2482                             aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
   2483         }
   2484     }
   2485     else
   2486     {
   2487         // Event from unknown node or component. Do nothing but log it
   2488         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleNodeInformationalEvent() Info event from unknown node Event type 0x%x Context 0x%x Data 0x%x",
   2489                         aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
   2490     }
   2491 
   2492     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeInformationalEvent() Out"));
   2493 }
   2494 
   2495 
   2496 void PVPlayerEngine::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent)
   2497 {
   2498     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeErrorEvent() In"));
   2499 
   2500     PVMFNodeInterface* nodeorigin = (PVMFNodeInterface*)(aEvent.GetContext());
   2501 
   2502     PVPlayerNodeType nodetype = PVP_NODETYPE_UNKNOWN;
   2503     int32 datapathindex = -1;
   2504 
   2505     // Process the error event based on the node type reporting the event
   2506     if (nodeorigin == iSourceNode)
   2507     {
   2508         HandleSourceNodeErrorEvent(aEvent);
   2509     }
   2510     else if (FindNodeTypeByNode(nodeorigin, nodetype, datapathindex) == true)
   2511     {
   2512         if (nodetype == PVP_NODETYPE_SINK)
   2513         {
   2514             HandleSinkNodeErrorEvent(aEvent, datapathindex);
   2515         }
   2516         else if (nodetype == PVP_NODETYPE_DECODER)
   2517         {
   2518             HandleDecNodeErrorEvent(aEvent, datapathindex);
   2519         }
   2520         else
   2521         {
   2522             // Event from unknown node or component. Do nothing but log it
   2523             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleNodeErrorEvent() Error event from unknown node type Event type 0x%x Context 0x%x Data 0x%x",
   2524                             aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
   2525         }
   2526     }
   2527     else
   2528     {
   2529         // Event from unknown node or component. Do nothing but log it
   2530         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleNodeErrorEvent() Error event from unknown node Event type 0x%x Context 0x%x Data 0x%x",
   2531                         aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
   2532     }
   2533 
   2534     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeErrorEvent() Out"));
   2535 }
   2536 
   2537 void PVPlayerEngine::RemoveDatapathContextFromList()
   2538 {
   2539     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDatapathContextFromList(): Erasing from ContextList iCurrentContextList.size() in : %d",
   2540                     iCurrentContextList.size()));
   2541     for (int32 i = iCurrentContextList.size() - 1; i >= 0; --i)
   2542     {
   2543         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDatapathContextFromList(): iCurrentContextList[i]->iCmdType %d",
   2544                         iCurrentContextList[i]->iCmdType));
   2545 
   2546         switch (iCurrentContextList[i]->iCmdType)
   2547         {
   2548             case PVP_CMD_DPPrepare:
   2549             case PVP_CMD_DPStart:
   2550             case PVP_CMD_DPStop:
   2551             case PVP_CMD_DPTeardown:
   2552             case PVP_CMD_DPReset:
   2553                 FreeEngineContext(iCurrentContextList[i]);
   2554                 break;
   2555             default:
   2556                 break;
   2557         }
   2558     }
   2559     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDatapathContextFromList(): iCurrentContextList.size() out : %d",
   2560                     iCurrentContextList.size()));
   2561 }
   2562 
   2563 
   2564 void PVPlayerEngine::HandlePlayerDatapathEvent(int32 /*aDatapathEvent*/, PVMFStatus aEventStatus, OsclAny* aContext, PVMFCmdResp* aCmdResp)
   2565 {
   2566     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() In"));
   2567 
   2568     // Check if a cancel command completed
   2569     uint32* context_uint32 = (uint32*)aContext;
   2570     if (context_uint32 == &iNumberCancelCmdPending)
   2571     {
   2572         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Cancel in datapath completed for cancel command. Pending %d", iNumberCancelCmdPending));
   2573         --iNumberCancelCmdPending;
   2574         if (iNumberCancelCmdPending == 0)
   2575         {
   2576             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Cancelling of all node/datapath commands complete, now reset all nodes"));
   2577             // Clear the CancelCmd queue as the cmd has been cancelled.
   2578             iCmdToCancel.clear();
   2579 
   2580             RemoveDatapathContextFromList(); // empty left over contexts from cancelled datapath commands
   2581             // Now reset the source node
   2582             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   2583 
   2584             PVMFCommandId cmdid = -1;
   2585             int32 leavecode = 0;
   2586             OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   2587             OSCL_FIRST_CATCH_ANY(leavecode,
   2588 
   2589                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Reset on iSourceNode did a leave!"));
   2590                                  FreeEngineContext(context);
   2591                                  OSCL_ASSERT(false);
   2592                                  return);
   2593 
   2594             SetEngineState(PVP_ENGINE_STATE_RESETTING);
   2595         }
   2596         return;
   2597     }
   2598 
   2599     PVPlayerEngineContext* datapathcontext = (PVPlayerEngineContext*)aContext;
   2600     OSCL_ASSERT(datapathcontext);
   2601 
   2602     // Ignore other datapath event if cancelling
   2603     if (!iCmdToCancel.empty() || (CheckForPendingErrorHandlingCmd() && (aCmdResp && aCmdResp->GetCmdStatus() == PVMFErrCancelled)))
   2604     {
   2605         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Datapath event ignored due to cancel process"));
   2606         // Remove the context from the list
   2607         FreeEngineContext(datapathcontext);
   2608         return;
   2609     }
   2610 
   2611     // Process the datapath event based on the engine state
   2612     if (iState == PVP_ENGINE_STATE_PREPARING)
   2613     {
   2614         switch (datapathcontext->iCmdType)
   2615         {
   2616             case PVP_CMD_DPPrepare:
   2617                 HandleDatapathPrepare(*datapathcontext, aEventStatus, aCmdResp);
   2618                 break;
   2619 
   2620             case PVP_CMD_DPStart:
   2621                 HandleDatapathStart(*datapathcontext, aEventStatus, aCmdResp);
   2622                 break;
   2623 
   2624             default:
   2625                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid datapath command type in PVP_ENGINE_STATE_PREPARING."));
   2626                 break;
   2627         }
   2628     }
   2629     else if (iState == PVP_ENGINE_STATE_PAUSING)
   2630     {
   2631         HandleDatapathPause(*datapathcontext, aEventStatus, aCmdResp);
   2632     }
   2633     else if (iState == PVP_ENGINE_STATE_RESUMING)
   2634     {
   2635         HandleDatapathResume(*datapathcontext, aEventStatus, aCmdResp);
   2636     }
   2637     else if (iState == PVP_ENGINE_STATE_STOPPING)
   2638     {
   2639         switch (datapathcontext->iCmdType)
   2640         {
   2641             case PVP_CMD_DPStop:
   2642                 HandleDatapathStop(*datapathcontext, aEventStatus, aCmdResp);
   2643                 break;
   2644 
   2645             case PVP_CMD_DPTeardown:
   2646                 HandleDatapathTeardown(*datapathcontext, aEventStatus, aCmdResp);
   2647                 break;
   2648 
   2649             case PVP_CMD_DPReset:
   2650                 HandleDatapathReset(*datapathcontext, aEventStatus, aCmdResp);
   2651                 break;
   2652 
   2653             default:
   2654                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid datapath command type in PVP_ENGINE_STATE_STOPPING."));
   2655                 break;
   2656         }
   2657     }
   2658     else if (iState == PVP_ENGINE_STATE_RESETTING)
   2659     {
   2660         switch (datapathcontext->iCmdType)
   2661         {
   2662             case PVP_CMD_DPReset:
   2663                 HandleDatapathReset(*datapathcontext, aEventStatus, aCmdResp);
   2664                 break;
   2665 
   2666             default:
   2667                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid datapath command type in PVP_ENGINE_STATE_RESETTING"));
   2668                 break;
   2669         }
   2670     }
   2671     else
   2672     {
   2673         // Unknown datapath.
   2674         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid state for datapath command completion."));
   2675     }
   2676 
   2677     // Remove the context from the list
   2678     FreeEngineContext(datapathcontext);
   2679 
   2680     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Out"));
   2681 }
   2682 
   2683 void PVPlayerEngine::NotificationsInterfaceDestroyed()
   2684 {
   2685     iClockNotificationsInf = NULL;
   2686 }
   2687 
   2688 void PVPlayerEngine::ProcessCallBack(uint32 aCallBackID, PVTimeComparisonUtils::MediaTimeStatus aTimerAccuracy, uint32 aDelta,
   2689                                      const OsclAny* acontextData, PVMFStatus aStatus)
   2690 {
   2691     OSCL_UNUSED_ARG(aTimerAccuracy);
   2692     OSCL_UNUSED_ARG(aDelta);
   2693     OSCL_UNUSED_ARG(acontextData);
   2694 
   2695     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::TimeoutOccurred() Timer for PlayStatus event triggered"));
   2696 
   2697     if (aCallBackID == iPlayStatusCallbackTimerID)
   2698     {
   2699         //Callback timer needs to be restarted if status is success
   2700         if ((PVMFSuccess == aStatus) && iPlayStatusTimerEnabled)
   2701         {
   2702             SendPositionStatusUpdate();
   2703             iPlayStatusTimerEnabled = false;
   2704             iPlayStatusCallbackTimerID = 0;
   2705 
   2706             StartPlaybackStatusTimer();
   2707         }
   2708         else
   2709         {
   2710             if (aStatus == PVMFErrCallbackClockStopped)
   2711             {
   2712                 iPlayStatusTimerEnabled = false;
   2713                 iPlayStatusCallbackTimerID = 0;
   2714             }
   2715         }
   2716     }
   2717 }
   2718 void PVPlayerEngine::SendPositionStatusUpdate(void)
   2719 {
   2720     PVPPlaybackPosition curpos;
   2721     curpos.iPosUnit = iPBPosStatusUnit;
   2722     GetPlaybackClockPosition(curpos);
   2723 
   2724     uint8 poslocalbuffer[8];
   2725     oscl_memset(poslocalbuffer, 0, 8);
   2726     poslocalbuffer[0] = 1;
   2727     switch (iPBPosStatusUnit)
   2728     {
   2729         case PVPPBPOSUNIT_SEC:
   2730             oscl_memcpy(&poslocalbuffer[4], &(curpos.iPosValue.sec_value), sizeof(uint32));
   2731             break;
   2732 
   2733         case PVPPBPOSUNIT_MIN:
   2734             oscl_memcpy(&poslocalbuffer[4], &(curpos.iPosValue.min_value), sizeof(uint32));
   2735             break;
   2736 
   2737         case PVPPBPOSUNIT_MILLISEC:
   2738         default:
   2739             oscl_memcpy(&poslocalbuffer[4], &(curpos.iPosValue.millisec_value), sizeof(uint32));
   2740             break;
   2741     }
   2742 
   2743     PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   2744     PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackPositionStatus, puuid, NULL));
   2745     // EventData parameter will be deprecated, and curpos will not be sent through EventData in future.
   2746     SendInformationalEvent(PVMFInfoPositionStatus, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&curpos, poslocalbuffer, 8);
   2747     infomsg->removeRef();
   2748 }
   2749 
   2750 
   2751 void PVPlayerEngine::TimeoutOccurred(int32 timerID, int32 /*timeoutInfo*/)
   2752 {
   2753     if (timerID == PVPLAYERENGINE_TIMERID_ENDTIMECHECK)
   2754     {
   2755         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::TimeoutOccurred() Timer for EndTime check triggered"));
   2756 
   2757         PVPPlaybackPosition curpos;
   2758         curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   2759         GetPlaybackClockPosition(curpos);
   2760 
   2761         if (iCurrentEndPosition.iIndeterminate || iCurrentEndPosition.iPosUnit != PVPPBPOSUNIT_MILLISEC)
   2762         {
   2763             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::TimeoutOccurred() End time unit is invalid. Disabling end time check."));
   2764             iEndTimeCheckEnabled = false;
   2765             iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   2766             OSCL_ASSERT(false);
   2767             return;
   2768         }
   2769 
   2770         if (curpos.iPosValue.millisec_value >= iCurrentEndPosition.iPosValue.millisec_value)
   2771         {
   2772             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::TimeoutOccurred() Specified end time reached so issuing pause command"));
   2773 
   2774             iEndTimeCheckEnabled = false;
   2775             iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   2776             // Issues end time reached command
   2777             AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED, NULL, NULL, NULL, false);
   2778         }
   2779         else if (!iEndTimeCheckEnabled)
   2780         {
   2781             iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   2782         }
   2783     }
   2784 }
   2785 
   2786 void PVPlayerEngine::RecognizeCompleted(PVMFFormatType aSourceFormatType, OsclAny* aContext)
   2787 {
   2788     // Check if a cancel command completed
   2789     uint32* context_uint32 = (uint32*)(aContext);
   2790     if (context_uint32 == &iNumberCancelCmdPending)
   2791     {
   2792         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RecognizeCompleted() Recognize request cancelled"));
   2793         --iNumberCancelCmdPending;
   2794         if (iNumberCancelCmdPending == 0)
   2795         {
   2796             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RecognizeCompleted() Cancelling of all node/datapath commands complete, now reset all nodes"));
   2797             // Clear the CancelCmd queue as the cmd has been cancelled.
   2798             iCmdToCancel.clear();
   2799 
   2800             RemoveDatapathContextFromList(); // empty left over contexts from cancelled datapath commands
   2801             // Now reset the source node
   2802             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   2803 
   2804             PVMFCommandId cmdid = -1;
   2805             int32 leavecode = 0;
   2806             OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   2807             OSCL_FIRST_CATCH_ANY(leavecode,
   2808 
   2809                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RecognizeCompleted() Reset on iSourceNode did a leave!"));
   2810                                  FreeEngineContext(context);
   2811                                  OSCL_ASSERT(false);
   2812                                  return);
   2813 
   2814             SetEngineState(PVP_ENGINE_STATE_RESETTING);
   2815         }
   2816         return;
   2817     }
   2818 
   2819     // Ignore recognize completion if cancelling
   2820     if (!iCmdToCancel.empty() || CheckForPendingErrorHandlingCmd())
   2821     {
   2822         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RecognizeCompleted() Recognize completion ignored due to cancel process"));
   2823         // Remove the context from the list
   2824         FreeEngineContext((PVPlayerEngineContext*)(aContext));
   2825         return;
   2826     }
   2827 
   2828     // Save the recognized source format
   2829     iSourceFormatType = aSourceFormatType;
   2830 
   2831     // Free the engine context after saving the cmd id and context
   2832     PVPlayerEngineContext* reccontext = (PVPlayerEngineContext*)(aContext);
   2833     OSCL_ASSERT(reccontext != NULL);
   2834     PVCommandId cmdid = reccontext->iCmdId;
   2835     OsclAny* cmdcontext = reccontext->iCmdContext;
   2836     FreeEngineContext(reccontext);
   2837 
   2838     // Start the source node creation and setup sequence
   2839     PVMFStatus retval = DoSetupSourceNode(cmdid, cmdcontext);
   2840 
   2841     if (retval != PVMFSuccess)
   2842     {
   2843         bool ehPending = CheckForPendingErrorHandlingCmd();
   2844         if (ehPending)
   2845         {
   2846             // there should be no error handling queued.
   2847             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RecognizeCompleted() Already EH pending, should never happen"));
   2848             return;
   2849         }
   2850         else
   2851         {
   2852             // Queue up Error Handling
   2853             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RecognizeCompleted() DoSetupSourceNode failed, Add EH command"));
   2854             iCommandCompleteStatusInErrorHandling = retval;
   2855             iCommandCompleteErrMsgInErrorHandling = NULL;
   2856             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
   2857         }
   2858         return;
   2859     }
   2860 }
   2861 
   2862 //A callback from the threadsafe queue
   2863 void PVPlayerEngine::ThreadSafeQueueDataAvailable(ThreadSafeQueue* aQueue)
   2864 {
   2865     OSCL_UNUSED_ARG(aQueue);
   2866 
   2867     //pull all available data off the thread-safe queue and transfer
   2868     //it to the internal queue.
   2869     for (uint32 ndata = 1; ndata;)
   2870     {
   2871         ThreadSafeQueueId id;
   2872         OsclAny* data;
   2873         ndata = iThreadSafeQueue.DeQueue(id, data);
   2874         if (ndata)
   2875         {
   2876             PVPlayerEngineCommand* cmd = (PVPlayerEngineCommand*)data;
   2877             AddCommandToQueue(cmd->iCmdType
   2878                               , cmd->iContextData
   2879                               , &cmd->iParamVector
   2880                               , &cmd->iUuid
   2881                               , true//assume all out-of-thread data is an API command.
   2882                               , (PVCommandId*)&id);//use the command ID that was returned to the caller.
   2883             OSCL_DELETE(cmd);
   2884         }
   2885     }
   2886 }
   2887 
   2888 PVMFStatus PVPlayerEngine::DoOOTSyncCommand(int32 aCmdType,
   2889         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator>* aParamVector,
   2890         const PVUuid* aUuid)
   2891 {
   2892     //Called from out-of-thread to perform a synchronous command
   2893 
   2894 
   2895     //Add a PVMFStatus* to the end of the command param vec to hold the result.
   2896     PVMFStatus status;
   2897     PVPlayerEngineCommandParamUnion param;
   2898     param.pOsclAny_value = (OsclAny*) & status;
   2899     aParamVector->push_back(param);
   2900 
   2901     //push the command across the thread boundary
   2902     PVCommandId id = 0;
   2903     PVPlayerEngineCommand* cmd = OSCL_NEW(PVPlayerEngineCommand, (aCmdType, id, NULL, aParamVector));
   2904     if (aUuid)
   2905         cmd->SetUuid(*aUuid);
   2906     iThreadSafeQueue.AddToQueue(cmd);
   2907 
   2908     //block and wait for completion by engine thread.
   2909     iOOTSyncCommandSem.Wait();
   2910     return status;
   2911 }
   2912 
   2913 void PVPlayerEngine::OOTSyncCommandComplete(PVPlayerEngineCommand& aCmd, PVMFStatus aStatus)
   2914 {
   2915     //Called in engine thread to complete an out-of-thread synchronous command
   2916 
   2917     //Put the result status into the last element of the command param vector.
   2918     PVMFStatus* status = (PVMFStatus*)(aCmd.GetParam(aCmd.iParamVector.size() - 1).pOsclAny_value);
   2919     OSCL_ASSERT(status);
   2920     *status = aStatus;
   2921 
   2922     //Signal the calling thread.
   2923     iOOTSyncCommandSem.Signal();
   2924 }
   2925 
   2926 PVCommandId PVPlayerEngine::AddCommandToQueue(int32 aCmdType, OsclAny* aContextData,
   2927         Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator>* aParamVector,
   2928         const PVUuid* aUuid, bool aAPICommand, PVCommandId* aId)
   2929 {
   2930     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AddCommandToQueue() In CmdType %d, CmdId %d", aCmdType, iCommandId));
   2931 
   2932     PVCommandId commandId;
   2933     if (aId)
   2934     {
   2935         //This command is being transferred from the thread-safe queue to the
   2936         //internal queue, in engine thread context.
   2937         //The input ID is the one that was returned to the
   2938         //caller, so use that ID instead of generating a new one.
   2939         commandId = *aId;
   2940     }
   2941     else
   2942     {
   2943         //Generate the next command ID, being careful to avoid thread contention
   2944         //for "iCommandId".
   2945         iCommandIdMut.Lock();
   2946         commandId = iCommandId;
   2947         ++iCommandId;
   2948         if (iCommandId == 0x7FFFFFFF)
   2949         {
   2950             iCommandId = 0;
   2951         }
   2952         iCommandIdMut.Unlock();
   2953 
   2954         //If this is from outside engine thread context, then push the command across the
   2955         //thread boundary.
   2956         if (!iThreadSafeQueue.IsInThread())
   2957         {
   2958             PVPlayerEngineCommand* cmd = OSCL_NEW(PVPlayerEngineCommand, (aCmdType, commandId, aContextData, aParamVector, aAPICommand));
   2959             if (aUuid)
   2960                 cmd->SetUuid(*aUuid);
   2961             iThreadSafeQueue.AddToQueue(cmd, (ThreadSafeQueueId*)&commandId);
   2962             return commandId;
   2963         }
   2964     }
   2965 
   2966     PVPlayerEngineCommand cmd(aCmdType, commandId, aContextData, aParamVector, aAPICommand);
   2967     if (aUuid)
   2968     {
   2969         cmd.SetUuid(*aUuid);
   2970     }
   2971 
   2972     int32 leavecode = 0;
   2973     OSCL_TRY(leavecode, iPendingCmds.push(cmd));
   2974     OSCL_FIRST_CATCH_ANY(leavecode,
   2975                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::AddCommandToQueue() Adding command to pending command list did a leave!"));
   2976                          OSCL_ASSERT(false);
   2977                          return -1;);
   2978 
   2979     // if engine needs to queue any error handling command set the engine state as PVP_ENGINE_STATE_ERROR.
   2980     switch (aCmdType)
   2981     {
   2982         case PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE:
   2983         case PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT:
   2984         case PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE:
   2985         case PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE:
   2986         case PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME:
   2987         case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE:
   2988         case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE:
   2989         case PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP:
   2990         case PVP_ENGINE_COMMAND_ERROR_HANDLING_CANCEL_ALL_COMMANDS:
   2991         case PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL:
   2992             SetEngineState(PVP_ENGINE_STATE_ERROR);
   2993             SendInformationalEvent(PVMFInfoErrorHandlingStart, NULL);
   2994             break;
   2995 
   2996         default:
   2997             break;
   2998     }
   2999 
   3000     RunIfNotReady();
   3001 
   3002     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   3003                     (0, "PVPlayerEngine::AddCommandToQueue() Type=%d ID=%d APIcmd=%d Tick=%d",
   3004                      aCmdType, cmd.GetCmdId(), aAPICommand, OsclTickCount::TickCount()));
   3005 
   3006     return cmd.GetCmdId();
   3007 }
   3008 
   3009 
   3010 void PVPlayerEngine::SetEngineState(PVPlayerEngineState aState)
   3011 {
   3012     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetEngineState() In Current state %d, New state %d", iState, aState));
   3013     iState = aState;
   3014 }
   3015 
   3016 
   3017 PVPlayerState PVPlayerEngine::GetPVPlayerState(void)
   3018 {
   3019     switch (iState)
   3020     {
   3021         case PVP_ENGINE_STATE_IDLE:
   3022         case PVP_ENGINE_STATE_INITIALIZING:
   3023             return PVP_STATE_IDLE;
   3024 
   3025         case PVP_ENGINE_STATE_INITIALIZED:
   3026         case PVP_ENGINE_STATE_PREPARING:
   3027         case PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE:
   3028         case PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE:
   3029         case PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE:
   3030             return PVP_STATE_INITIALIZED;
   3031 
   3032         case PVP_ENGINE_STATE_PREPARED:
   3033         case PVP_ENGINE_STATE_STARTING:
   3034             return PVP_STATE_PREPARED;
   3035 
   3036         case PVP_ENGINE_STATE_STARTED:
   3037         case PVP_ENGINE_STATE_AUTO_PAUSING:
   3038         case PVP_ENGINE_STATE_AUTO_PAUSED:
   3039         case PVP_ENGINE_STATE_AUTO_RESUMING:
   3040         case PVP_ENGINE_STATE_PAUSING:
   3041         case PVP_ENGINE_STATE_STOPPING:
   3042             return PVP_STATE_STARTED;
   3043 
   3044         case PVP_ENGINE_STATE_PAUSED:
   3045         case PVP_ENGINE_STATE_RESUMING:
   3046             return PVP_STATE_PAUSED;
   3047 
   3048         case PVP_ENGINE_STATE_RESETTING:
   3049         {
   3050             bool ehPending = CheckForPendingErrorHandlingCmd();
   3051             if (ehPending)
   3052             {
   3053                 return PVP_STATE_ERROR;
   3054             }
   3055             else
   3056             {
   3057                 return PVP_STATE_IDLE;
   3058             }
   3059         }
   3060 
   3061         case PVP_ENGINE_STATE_ERROR:
   3062             return PVP_STATE_ERROR;
   3063 
   3064         default:
   3065             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetPVPlayerState() Unknown engine state. Asserting"));
   3066             OSCL_ASSERT(false);
   3067             break;
   3068     }
   3069 
   3070     return PVP_STATE_ERROR;
   3071 }
   3072 
   3073 
   3074 void PVPlayerEngine::GetPlaybackClockPosition(PVPPlaybackPosition& aClockPos)
   3075 {
   3076     bool tmpbool = false;
   3077     uint32 clockcurpos = 0;
   3078     aClockPos.iIndeterminate = false;
   3079 
   3080     int32 nptcurpos;
   3081 
   3082     if (!iChangeDirectionNPT.iIndeterminate)
   3083     {
   3084         // report the expected NPT after the direction change
   3085         // to avoid weird transient values between the direction change
   3086         // and the repositioning completion.
   3087         nptcurpos = iChangeDirectionNPT.iPosValue.millisec_value;
   3088     }
   3089     else
   3090     {
   3091         // Get current playback clock position
   3092         iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   3093 
   3094         nptcurpos = iStartNPT + iPlaybackDirection * (clockcurpos - iStartMediaDataTS);
   3095     }
   3096     if (nptcurpos < 0)
   3097     {
   3098         nptcurpos = 0;
   3099     }
   3100 
   3101     if (ConvertFromMillisec((uint32)nptcurpos, aClockPos) != PVMFSuccess)
   3102     {
   3103         // Other position units are not supported yet
   3104         aClockPos.iIndeterminate = true;
   3105     }
   3106 }
   3107 
   3108 
   3109 PVMFStatus PVPlayerEngine::ConvertToMillisec(PVPPlaybackPosition& aPBPos, uint32& aTimeMS)
   3110 {
   3111     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertToMillisec() In"));
   3112 
   3113     if (aPBPos.iIndeterminate)
   3114     {
   3115         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertToMillisec() Indeterminate position"));
   3116         return PVMFErrArgument;
   3117     }
   3118 
   3119     bool owallclockunits = false;
   3120     switch (aPBPos.iPosUnit)
   3121     {
   3122         case PVPPBPOSUNIT_MILLISEC:
   3123             aTimeMS = aPBPos.iPosValue.millisec_value;
   3124             owallclockunits = true;
   3125             break;
   3126 
   3127         case PVPPBPOSUNIT_SEC:
   3128             aTimeMS = aPBPos.iPosValue.sec_value * 1000;
   3129             owallclockunits = true;
   3130             break;
   3131 
   3132         case PVPPBPOSUNIT_MIN:
   3133             aTimeMS = aPBPos.iPosValue.min_value * 60000;
   3134             owallclockunits = true;
   3135             break;
   3136 
   3137         case PVPPBPOSUNIT_HOUR:
   3138             aTimeMS = aPBPos.iPosValue.hour_value * 3600000;
   3139             owallclockunits = true;
   3140             break;
   3141 
   3142         case PVPPBPOSUNIT_SMPTE:
   3143             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() SMPTE not supported yet"));
   3144             return PVMFErrArgument;
   3145 
   3146         case PVPPBPOSUNIT_PERCENT:
   3147         {
   3148             if (iSourceDurationAvailable == false)
   3149             {
   3150                 // Duration info not available from source node so can't convert
   3151                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Duration not available so can't convert"));
   3152                 return PVMFErrArgument;
   3153             }
   3154 
   3155             if (iSourceDurationInMS == 0)
   3156             {
   3157                 // Duration is 0 so can't convert
   3158                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Duration value is 0 so can't convert"));
   3159                 return PVMFErrArgument;
   3160             }
   3161 
   3162             if (aPBPos.iPosValue.percent_value >= 100)
   3163             {
   3164                 // If percentage greater than 100, cap to 100%
   3165                 aTimeMS = iSourceDurationInMS;
   3166             }
   3167             else
   3168             {
   3169                 // Calculate time in millseconds based on percentage of duration
   3170                 aTimeMS = (aPBPos.iPosValue.percent_value * iSourceDurationInMS) / 100;
   3171             }
   3172         }
   3173         break;
   3174 
   3175         case PVPPBPOSUNIT_SAMPLENUMBER:
   3176         {
   3177             if (iSourceNodeTrackLevelInfoIF == NULL)
   3178             {
   3179                 // The source node doesn't have the query IF to convert samplenum to time
   3180                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Sample number to time conversion not available"));
   3181                 return PVMFErrArgument;
   3182             }
   3183 
   3184             // Determine which track to use for conversion.
   3185             // Give preference to video track, then text, and finally audio
   3186             PVMFTrackInfo* track = NULL;
   3187             int32 datapathIndex = -1;
   3188 
   3189             // Search from the datapath list.
   3190             // 1) Try for video track
   3191             bool retVal = FindDatapathForTrackUsingMimeString(true, false, false, datapathIndex);
   3192             if (retVal == false)
   3193             {
   3194                 // Video track not available, look for text track
   3195                 retVal = FindDatapathForTrackUsingMimeString(false, false, true, datapathIndex);
   3196                 if (retVal == false)
   3197                 {
   3198                     // Text track also not avaliable, look for audio track
   3199                     retVal = FindDatapathForTrackUsingMimeString(false, true, false, datapathIndex);
   3200                     if (retVal == false)
   3201                     {
   3202                         // Track is not available to do the conversion
   3203                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Track not selected for conversion"));
   3204                         return PVMFErrArgument;
   3205                     }
   3206                 }
   3207             }
   3208 
   3209             // Track avalaible.
   3210             track = iDatapathList[datapathIndex].iTrackInfo;
   3211 
   3212             // Convert the sample number to time in milliseconds
   3213             PVMFTimestamp framets = 0;
   3214             if (iSourceNodeTrackLevelInfoIF->GetTimestampForSampleNumber(*track, aPBPos.iPosValue.samplenum_value, framets) != PVMFSuccess)
   3215             {
   3216                 // Conversion failed
   3217                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Sample number to time conversion failed"));
   3218                 return PVMFErrArgument;
   3219             }
   3220 
   3221             aTimeMS = framets;
   3222         }
   3223         break;
   3224 
   3225         case PVPPBPOSUNIT_DATAPOSITION:
   3226         {
   3227             if (iSourceNodeTrackLevelInfoIF == NULL)
   3228             {
   3229                 // The source node doesn't have the ext IF to convert data position to time
   3230                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Data position to time conversion not available"));
   3231                 return PVMFErrArgument;
   3232             }
   3233 
   3234             // Go through each active track and find the minimum time for given data position
   3235             bool mintsvalid = false;
   3236             PVMFTimestamp mints = 0xFFFFFFFF;
   3237             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   3238             {
   3239                 if (iDatapathList[i].iDatapath)
   3240                 {
   3241                     PVMFTimestamp curts = 0;
   3242                     if (iSourceNodeTrackLevelInfoIF->GetTimestampForDataPosition(*(iDatapathList[i].iTrackInfo), aPBPos.iPosValue.datapos_value, curts) != PVMFSuccess)
   3243                     {
   3244                         // Conversion failed
   3245                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Data position to time conversion failed"));
   3246                     }
   3247                     else
   3248                     {
   3249                         // Conversion succeeded. Save only if it is the minimum encountered so far.
   3250                         mintsvalid = true;
   3251                         if (curts < mints)
   3252                         {
   3253                             mints = curts;
   3254                         }
   3255                     }
   3256                 }
   3257             }
   3258 
   3259             if (mintsvalid == false)
   3260             {
   3261                 // Conversion on all active tracks failed
   3262                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Data position to time conversion could not be done on any active track"));
   3263                 return PVMFErrArgument;
   3264             }
   3265 
   3266             aTimeMS = mints;
   3267         }
   3268         break;
   3269 
   3270         case PVPPBPOSUNIT_PLAYLIST:
   3271         {
   3272             switch (aPBPos.iPlayListPosUnit)
   3273             {
   3274                 case PVPPBPOSUNIT_MILLISEC:
   3275                     aTimeMS = aPBPos.iPlayListPosValue.millisec_value;
   3276                     break;
   3277 
   3278                 case PVPPBPOSUNIT_SEC:
   3279                     aTimeMS = aPBPos.iPlayListPosValue.sec_value * 1000;
   3280                     break;
   3281 
   3282                 case PVPPBPOSUNIT_MIN:
   3283                     aTimeMS = aPBPos.iPlayListPosValue.min_value * 60000;
   3284                     break;
   3285 
   3286                 case PVPPBPOSUNIT_HOUR:
   3287                     aTimeMS = aPBPos.iPlayListPosValue.hour_value * 3600000;
   3288                     break;
   3289 
   3290                 default:
   3291                     // Don't support the other units for now
   3292                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Unsupported playlist position units"));
   3293                     return PVMFErrArgument;
   3294             }
   3295         }
   3296         break;
   3297 
   3298         default:
   3299             // Don't support the other units for now
   3300             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Unsupported position units"));
   3301             return PVMFErrArgument;
   3302     }
   3303 
   3304     if (owallclockunits == true)
   3305     {
   3306         if ((aTimeMS > iSourceDurationInMS) && (iSourceDurationAvailable == true))
   3307         {
   3308             //cap time to clip duration
   3309             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVPlayerEngine::ConvertToMillisec() Capping value - Acutal=%d, CappedValue=%d",
   3310                             aTimeMS, iSourceDurationInMS));
   3311             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_DEBUG, (0, "PVPlayerEngine::ConvertToMillisec() Capping value - Acutal=%d, CappedValue=%d",
   3312                             aTimeMS, iSourceDurationInMS));
   3313             aTimeMS = iSourceDurationInMS;
   3314         }
   3315         else
   3316         {
   3317             // just pass the converted time even if duration is not available and let
   3318             // source node handle the request.
   3319         }
   3320     }
   3321 
   3322     if (aPBPos.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
   3323     {
   3324         aPBPos.iPlayListPosValue.millisec_value = aTimeMS;
   3325         aPBPos.iPlayListPosUnit = PVPPBPOSUNIT_MILLISEC;
   3326     }
   3327     else
   3328     {
   3329         aPBPos.iPosValue.millisec_value = aTimeMS;
   3330         aPBPos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   3331     }
   3332     iTargetNPT = aTimeMS;
   3333 
   3334     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ConvertToMillisec() Out"));
   3335     return PVMFSuccess;
   3336 }
   3337 
   3338 
   3339 PVMFStatus PVPlayerEngine::ConvertFromMillisec(uint32 aTimeMS, PVPPlaybackPosition& aPBPos)
   3340 {
   3341     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ConvertFromMillisec() In"));
   3342 
   3343     // Convert to specified time units
   3344     switch (aPBPos.iPosUnit)
   3345     {
   3346         case PVPPBPOSUNIT_MILLISEC:
   3347             aPBPos.iPosValue.millisec_value = aTimeMS;
   3348             break;
   3349 
   3350         case PVPPBPOSUNIT_SEC:
   3351             aPBPos.iPosValue.sec_value = aTimeMS / 1000;
   3352             break;
   3353 
   3354         case PVPPBPOSUNIT_MIN:
   3355             aPBPos.iPosValue.min_value = aTimeMS / 60000;
   3356             break;
   3357 
   3358         case PVPPBPOSUNIT_HOUR:
   3359             aPBPos.iPosValue.hour_value = aTimeMS / 3600000;
   3360             break;
   3361 
   3362         case PVPPBPOSUNIT_SMPTE:
   3363             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertFromMillisec() SMPTE units not supported yet"));
   3364             return PVMFErrArgument;
   3365 
   3366         case PVPPBPOSUNIT_PERCENT:
   3367         {
   3368             if (iSourceDurationAvailable == false)
   3369             {
   3370                 // Duration info not available from source node so can't convert
   3371                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Duration not available so can't convert"));
   3372                 return PVMFErrArgument;
   3373             }
   3374 
   3375             if (iSourceDurationInMS == 0)
   3376             {
   3377                 // Duration is 0 so can't convert
   3378                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Duration value is 0 so can't convert"));
   3379                 return PVMFErrArgument;
   3380             }
   3381 
   3382             if (aTimeMS >= iSourceDurationInMS)
   3383             {
   3384                 // Put a ceiling of 100%
   3385                 aPBPos.iPosValue.percent_value = 100;
   3386             }
   3387             else
   3388             {
   3389                 // Calculate percentage of playback, avoiding overflow
   3390                 if (iSourceDurationInMS >= PVP_MIN_PLAYSTATUS_PERCENT_OVERFLOW_THRESHOLD)
   3391                 {
   3392                     aPBPos.iPosValue.percent_value = aTimeMS / (iSourceDurationInMS / 100);
   3393                 }
   3394                 else
   3395                 {
   3396                     aPBPos.iPosValue.percent_value = (aTimeMS * 100) / iSourceDurationInMS;
   3397                 }
   3398             }
   3399         }
   3400         break;
   3401 
   3402         case PVPPBPOSUNIT_SAMPLENUMBER:
   3403         {
   3404             if (iSourceNodeTrackLevelInfoIF == NULL)
   3405             {
   3406                 // The source node doesn't have the query IF to convert time to sample number
   3407                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Time to sample numberconversion not available"));
   3408                 return PVMFErrArgument;
   3409             }
   3410 
   3411             // Determine which track to use for conversion.
   3412             // Give preference to video track, then text, and finally audio
   3413             PVMFTrackInfo* track = NULL;
   3414             int32 datapathIndex = -1;
   3415 
   3416             // Search from the datapath list.
   3417             // 1) Try for video track
   3418             bool retVal = FindDatapathForTrackUsingMimeString(true, false, false, datapathIndex);
   3419             if (retVal == false)
   3420             {
   3421                 // Video track not available, look for text track
   3422                 retVal = FindDatapathForTrackUsingMimeString(false, false, true, datapathIndex);
   3423                 if (retVal == false)
   3424                 {
   3425                     // Text track also not avaliable, look for audio track
   3426                     retVal = FindDatapathForTrackUsingMimeString(false, true, false, datapathIndex);
   3427                     if (retVal == false)
   3428                     {
   3429                         // Track is not available to do the conversion
   3430                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Track not selected for conversion"));
   3431                         return PVMFErrArgument;
   3432                     }
   3433                 }
   3434             }
   3435 
   3436             // Track avalaible.
   3437             track = iDatapathList[datapathIndex].iTrackInfo;
   3438 
   3439             // Convert the time to sample number
   3440             PVMFTimestamp ts = aTimeMS;
   3441             uint32 samplenum = 0;
   3442             if (iSourceNodeTrackLevelInfoIF->GetSampleNumberForTimestamp(*track, ts, samplenum) != PVMFSuccess)
   3443             {
   3444                 // Conversion failed
   3445                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Sample number to time conversion failed"));
   3446                 return PVMFErrArgument;
   3447             }
   3448 
   3449             aPBPos.iPosValue.samplenum_value = samplenum;
   3450         }
   3451         break;
   3452 
   3453         case PVPPBPOSUNIT_DATAPOSITION:
   3454         {
   3455             if (iSourceNodeTrackLevelInfoIF == NULL)
   3456             {
   3457                 // The source node doesn't have the ext IF to convert time to data position
   3458                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Time to data position conversion not available in source node"));
   3459                 return PVMFErrArgument;
   3460             }
   3461 
   3462             // Query each active track for its data position
   3463             // Return the max data position
   3464             PVMFTimestamp ts = aTimeMS;
   3465             uint32 maxdatapos = 0;
   3466             bool maxdataposvalid = false;
   3467 
   3468             // Go through each active track
   3469             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   3470             {
   3471                 if (iDatapathList[i].iDatapath)
   3472                 {
   3473                     uint32 curdatapos = 0;
   3474                     // Convert the time to data position
   3475                     if (iSourceNodeTrackLevelInfoIF->GetDataPositionForTimestamp(*(iDatapathList[i].iTrackInfo), ts, curdatapos) != PVMFSuccess)
   3476                     {
   3477                         // Conversion failed
   3478                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Time to data position conversion failed"));
   3479                     }
   3480                     else
   3481                     {
   3482                         // Save the data position if it is greater than
   3483                         // any position encountered so far.
   3484                         maxdataposvalid = true;
   3485                         if (curdatapos > maxdatapos)
   3486                         {
   3487                             maxdatapos = curdatapos;
   3488                         }
   3489                     }
   3490                 }
   3491             }
   3492 
   3493             if (maxdataposvalid == false)
   3494             {
   3495                 // Conversion failed for all active tracks
   3496                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Track not selected for conversion"));
   3497                 return PVMFErrArgument;
   3498             }
   3499             // Save the data position to return
   3500             aPBPos.iPosValue.datapos_value = maxdatapos;
   3501         }
   3502         break;;
   3503 
   3504         default:
   3505             // Don't support the other units for now
   3506             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertFromMillisec() Unsupported position units"));
   3507             return PVMFErrArgument;
   3508     }
   3509 
   3510     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ConvertFromMillisec() Out"));
   3511     return PVMFSuccess;
   3512 }
   3513 
   3514 
   3515 void PVPlayerEngine::EngineCommandCompleted(PVCommandId aId, OsclAny* aContext, PVMFStatus aStatus, PVInterface* aExtInterface, OsclAny* aEventData, int32 aEventDataSize)
   3516 {
   3517     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::EngineCommandCompleted() In CmdId %d, Status %d", aId, aStatus));
   3518 
   3519     // Update the current command vector
   3520 
   3521     // Assert if the current cmd is not saved or the cmd ID does not match
   3522     OSCL_ASSERT(iCurrentCmd.size() == 1);
   3523     OSCL_ASSERT(iCurrentCmd[0].GetCmdId() == aId);
   3524 
   3525     // Empty out the current cmd vector and set active if there are other pending commands
   3526     PVPlayerEngineCommand completedcmd(iCurrentCmd[0]);
   3527     iCurrentCmd.erase(iCurrentCmd.begin());
   3528     if (!iPendingCmds.empty())
   3529     {
   3530         RunIfNotReady();
   3531     }
   3532 
   3533     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   3534                     (0, "PVPlayerEngine::EngineCommandCompleted() Type=%d ID=%d APIcmd=%d Tick=%d",
   3535                      completedcmd.GetCmdType(), completedcmd.GetCmdId(), completedcmd.IsAPICommand(), OsclTickCount::TickCount()));
   3536 
   3537     // Send informational event or send other callback if needed
   3538     switch (completedcmd.GetCmdType())
   3539     {
   3540         case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP:
   3541             SendEndOfClipInfoEvent(aStatus, aExtInterface);
   3542             break;
   3543 
   3544         case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED:
   3545             SendEndTimeReachedInfoEvent(aStatus, aExtInterface);
   3546             break;
   3547 
   3548         case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW:
   3549             SendSourceUnderflowInfoEvent(aStatus, aExtInterface);
   3550             break;
   3551 
   3552         case PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY:
   3553             SendSourceDataReadyInfoEvent(aStatus, aExtInterface);
   3554             break;
   3555 
   3556         case PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS:
   3557             // Send callback to the specified observer
   3558             if (iCfgCapCmdObserver)
   3559             {
   3560                 iCfgCapCmdObserver->SignalEvent(aId);
   3561             }
   3562             break;
   3563 
   3564         default:
   3565             // None to be sent
   3566             break;
   3567     }
   3568 
   3569     // Send the command completed event
   3570     if (iCmdStatusObserver)
   3571     {
   3572         if (aId != -1 && completedcmd.IsAPICommand())
   3573         {
   3574             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::EngineCommandCompleted() Notifying engine command as completed. CmdId %d Status %d", aId, aStatus));
   3575             PVCmdResponse cmdcompleted(aId, aContext, aStatus, aExtInterface, aEventData, aEventDataSize);
   3576             iCmdStatusObserver->CommandCompleted(cmdcompleted);
   3577         }
   3578         else
   3579         {
   3580             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::EngineCommandCompleted() aId is -1 or not an API command. CmdType %d", completedcmd.GetCmdType()));
   3581         }
   3582     }
   3583     else
   3584     {
   3585         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::EngineCommandCompleted() iCmdStatusObserver is NULL"));
   3586     }
   3587 }
   3588 
   3589 
   3590 void PVPlayerEngine::SendInformationalEvent(PVMFEventType aEventType, PVInterface* aExtInterface, OsclAny* aEventData, uint8* aLocalBuffer, uint32 aLocalBufferSize)
   3591 {
   3592     // Send the info event if observer has been specified
   3593     if (iInfoEventObserver)
   3594     {
   3595         PVAsyncInformationalEvent infoevent((PVEventType)aEventType, NULL, aExtInterface, (PVExclusivePtr)aEventData, aLocalBuffer, aLocalBufferSize);
   3596         iInfoEventObserver->HandleInformationalEvent(infoevent);
   3597     }
   3598     else
   3599     {
   3600         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SendInformationalEvent() iInfoEventObserver is NULL"));
   3601     }
   3602 }
   3603 
   3604 
   3605 void PVPlayerEngine::SendErrorEvent(PVMFEventType aEventType, PVInterface* aExtInterface, OsclAny* aEventData, uint8* aLocalBuffer, uint32 aLocalBufferSize)
   3606 {
   3607     // Send the error event if observer has been specified
   3608     if (iErrorEventObserver)
   3609     {
   3610         PVAsyncErrorEvent errorevent((PVEventType)aEventType, NULL, aExtInterface, (PVExclusivePtr)aEventData, aLocalBuffer, aLocalBufferSize);
   3611         iErrorEventObserver->HandleErrorEvent(errorevent);
   3612     }
   3613     else
   3614     {
   3615         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SendErrorEvent() iErrorEventObserver is NULL"));
   3616     }
   3617 }
   3618 
   3619 
   3620 void PVPlayerEngine::DoCancelCommand(PVPlayerEngineCommand& aCmd)
   3621 {
   3622     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommand() In"));
   3623 
   3624     // Boolean to check if the command is cancelled or not.
   3625     bool commandCancelled = false;
   3626 
   3627     // cmd to cancel either has been completed or is in pending queue.
   3628     // Create a temporary queue for pending commands and current command if any.
   3629     OsclPriorityQueue<PVPlayerEngineCommand, OsclMemAllocator, Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator>, PVPlayerEngineCommandCompareLess> iTempPendingCmds;
   3630     Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> iTempCurrentCmd;
   3631     // Copy the pending commands to the new queue
   3632     iTempPendingCmds = iPendingCmds;
   3633     while (!iTempPendingCmds.empty())
   3634     {
   3635         // Get the queue from the top
   3636         PVPlayerEngineCommand cmd(iTempPendingCmds.top());
   3637         // Check if it needs to be cancelled
   3638         if (aCmd.GetParam(0).int32_value == cmd.GetCmdId())
   3639         {
   3640             // Found command to be cancelled in the Pending Queue, set the
   3641             // commandCancelled boolean to true.
   3642             commandCancelled = true;
   3643 
   3644             // Remove it from the pending commands queue
   3645             iPendingCmds.remove(cmd);
   3646             // Save it temporary as "current command" and then cancel it. If CurrentCmd has some
   3647             // command, first move it to TempCurrentCmd queue.
   3648             if (!iCurrentCmd.empty())
   3649             {
   3650                 iTempCurrentCmd.push_front(iCurrentCmd[0]);
   3651                 iCurrentCmd.erase(iCurrentCmd.begin());
   3652             }
   3653 
   3654             iCurrentCmd.push_front(cmd);
   3655             EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), PVMFErrCancelled);
   3656 
   3657             // send command complete for CancelCommand also.
   3658             iCurrentCmd.push_front(aCmd);
   3659             EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   3660 
   3661             // If TempCurrentCmd queue is holding up any command, move it back to CurrentCmd queue.
   3662             if (!iTempCurrentCmd.empty())
   3663             {
   3664                 iCurrentCmd.push_front(iTempCurrentCmd[0]);
   3665                 iTempCurrentCmd.erase(iTempCurrentCmd.begin());
   3666             }
   3667         }
   3668         // Pop each cmd from the temporary queue
   3669         iTempPendingCmds.pop();
   3670     }
   3671 
   3672     if (!commandCancelled)
   3673     {
   3674         // There was no command cancelled, user might have given a wrong Argument
   3675         // Fail the command with PVMFErrArgument
   3676         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelCommand() Wrong Argument, No comand cancelled"));
   3677         if (!iCurrentCmd.empty())
   3678         {
   3679             PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
   3680             iCurrentCmd.erase(iCurrentCmd.begin());
   3681             iCurrentCmd.push_front(aCmd);
   3682             EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrArgument);
   3683             iCurrentCmd.push_front(currentcmd);
   3684         }
   3685         else
   3686         {
   3687             // Current Command is empty, just push CancelCommand and do Command Complete.
   3688             iCurrentCmd.push_front(aCmd);
   3689             EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrArgument);
   3690         }
   3691     }
   3692     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommand() Out"));
   3693 }
   3694 
   3695 
   3696 void PVPlayerEngine::DoCancelAllCommands(PVPlayerEngineCommand& aCmd)
   3697 {
   3698     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAllCommands() In"));
   3699 
   3700 
   3701     // Engine cannot be processing another cancel command
   3702     OSCL_ASSERT(iCmdToCancel.empty() == true);
   3703 
   3704     // While AcquireLicense and CancelAcquireLicense is processing, CancelAllCommands is prohibited.
   3705     if (!iCmdToDlaCancel.empty() ||
   3706             (!iCurrentCmd.empty() &&
   3707              (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE ||
   3708               iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR ||
   3709               iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR)))
   3710     {
   3711         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAllCommands() Error due to processing AcquireLicense or CancelAcquireLicense,CmdType=%d", iCurrentCmd[0].GetCmdType()));
   3712         PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
   3713         iCurrentCmd.erase(iCurrentCmd.begin());
   3714         iCurrentCmd.push_front(aCmd);
   3715         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrArgument);
   3716         iCurrentCmd.push_front(currentcmd);
   3717         return;
   3718     }
   3719     // set engine state to Resetting, as cancel command completion will take Engine to Idle state, after internal reset.
   3720     SetEngineState(PVP_ENGINE_STATE_RESETTING);
   3721     iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
   3722     // Stop the playback clock
   3723     iPlaybackClock.Stop();
   3724     // Cancel the current command first
   3725     if (iCurrentCmd.size() == 1)
   3726     {
   3727         // First save the current command being processed
   3728         iCmdToCancel.push_front(iCurrentCmd[0]);
   3729         // Cancel it
   3730         EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFErrCancelled);
   3731     }
   3732 
   3733     // Cancel all the pending commands
   3734 
   3735     // Create a temporary queue for pending commands
   3736     OsclPriorityQueue<PVPlayerEngineCommand, OsclMemAllocator, Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator>, PVPlayerEngineCommandCompareLess> iTempPendingCmds;
   3737     // Copy the pending commands to the new queue
   3738     iTempPendingCmds = iPendingCmds;
   3739     while (!iTempPendingCmds.empty())
   3740     {
   3741         // Get the queue from the top
   3742         PVPlayerEngineCommand cmd(iTempPendingCmds.top());
   3743         // Check if it needs to be cancelled
   3744         if ((aCmd.GetCmdId() > cmd.GetCmdId()) && !((aCmd.GetCmdId() - cmd.GetCmdId()) > 0x7FFFFFFF))
   3745         {
   3746             // Remove it from the pending commands queue
   3747             iPendingCmds.remove(cmd);
   3748             // Save it temporary as "current command" and then cancel it
   3749             iCurrentCmd.push_front(cmd);
   3750             EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), PVMFErrCancelled);
   3751         }
   3752         // Pop each cmd from the temporary queue
   3753         iTempPendingCmds.pop();
   3754     }
   3755 
   3756 
   3757     // Make the CancelAll() command the current command
   3758     iCurrentCmd.push_front(aCmd);
   3759 
   3760     // Check if there was an ongoing command that needs to be properly cancelled
   3761     if (!iCmdToCancel.empty())
   3762     {
   3763 
   3764         // Properly cancel a command being currently processed
   3765         DoCancelCommandBeingProcessed();
   3766     }
   3767     else
   3768     {
   3769         // Nothing to cancel, move on to resetting Source Nodes and Datapaths
   3770         if (iSourceNode)
   3771         {
   3772             int32 leavecode = 0;
   3773             // call reset on source node if not in created state
   3774             if (iSourceNode->GetState() != EPVMFNodeCreated)
   3775             {
   3776                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3777                                 (0, "PVPlayerEngine::DoCancelAllCommands() Issue reset on Source Node"));
   3778                 // error handling code set engine state to resetting
   3779                 SetEngineState(PVP_ENGINE_STATE_RESETTING);
   3780 
   3781                 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   3782 
   3783                 PVMFCommandId cmdid = -1;
   3784                 leavecode = 0;
   3785                 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   3786                 OSCL_FIRST_CATCH_ANY(leavecode,
   3787 
   3788                                      PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3789                                                      (0, "PVPlayerEngine::DoCancelAllCommands() Reset on iSourceNode did a leave!"));
   3790                                      FreeEngineContext(context);
   3791                                      OSCL_ASSERT(false););
   3792 
   3793                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAllCommands() Out"));
   3794                 return;
   3795             }
   3796         }
   3797 
   3798         if (iDataSource)
   3799         {
   3800             RemoveDataSourceSync(*iDataSource);
   3801         }
   3802         SetEngineState(PVP_ENGINE_STATE_IDLE);
   3803         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   3804     }
   3805 
   3806     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAllCommands() Out"));
   3807 }
   3808 
   3809 
   3810 void PVPlayerEngine::DoCancelCommandBeingProcessed(void)
   3811 {
   3812     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() In"));
   3813 
   3814     // There should be a command to cancel
   3815     OSCL_ASSERT(iCmdToCancel.empty() == false);
   3816 
   3817     // If cmd to cancel is GetMetadataKeys() or GetMetadataValues(), first release the memory for
   3818     // nodes which have already completed the call and then issue cancel on other nodes.
   3819     switch (iCmdToCancel[0].GetCmdType())
   3820     {
   3821         case PVP_ENGINE_COMMAND_GET_METADATA_KEY:
   3822         {
   3823             // Release the memory allocated for the metadata keys
   3824             while (iMetadataKeyReleaseList.empty() == false)
   3825             {
   3826                 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
   3827                 OSCL_ASSERT(mdif != NULL);
   3828                 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
   3829                 iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
   3830             }
   3831             // no need to break from the current switch, as we need to issue Cancel on nodes. Continue.
   3832         }
   3833         case PVP_ENGINE_COMMAND_GET_METADATA_VALUE:
   3834         {
   3835             // Release the memory allocated for the metadata values
   3836             while (iMetadataValueReleaseList.empty() == false)
   3837             {
   3838                 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
   3839                 OSCL_ASSERT(mdif != NULL);
   3840                 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
   3841                 iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
   3842             }
   3843 
   3844             iReleaseMetadataValuesPending = false;
   3845             // no need to break from the current switch, as we need to issue Cancel on nodes. Continue.
   3846         }
   3847         case PVP_ENGINE_COMMAND_ADD_DATA_SOURCE:
   3848         case PVP_ENGINE_COMMAND_INIT:
   3849         case PVP_ENGINE_COMMAND_PREPARE:
   3850         case PVP_ENGINE_COMMAND_PAUSE:
   3851         case PVP_ENGINE_COMMAND_RESUME:
   3852         case PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE:
   3853         case PVP_ENGINE_COMMAND_SET_PLAYBACK_RATE:
   3854         case PVP_ENGINE_COMMAND_CANCEL_COMMAND:
   3855         case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED:
   3856         case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP:
   3857         case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW:
   3858         case PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY:
   3859         case PVP_ENGINE_COMMAND_STOP:
   3860         {
   3861             // go ahead and issue cancel on nodes and datapath if needed.
   3862             if (!iCurrentContextList.empty())
   3863             {
   3864                 // Since there is a pending node or datapath, cancel it
   3865                 PVMFStatus status = DoCancelPendingNodeDatapathCommand();
   3866                 if (status == PVMFPending)
   3867                 {
   3868                     // There are some commands which need to be cancelled so wait for cancel complete
   3869                     // once cancels complete, we would start the reset sequence from either
   3870                     // NodeCommandComplete, HandlePlayerDataPathEvent, RecognizeComplete
   3871                     break;
   3872                 }
   3873             }
   3874 
   3875             // No pending command so reset the nodes now
   3876             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() No command to cancel, now reset all nodes"));
   3877 
   3878             // reset the source node
   3879             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   3880 
   3881             PVMFCommandId cmdid = -1;
   3882             int32 leavecode = 0;
   3883             OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   3884             OSCL_FIRST_CATCH_ANY(leavecode,
   3885 
   3886                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() Reset on iSourceNode did a leave!"));
   3887                                  FreeEngineContext(context);
   3888                                  OSCL_ASSERT(false);
   3889                                  return);
   3890 
   3891             SetEngineState(PVP_ENGINE_STATE_RESETTING);
   3892             break;
   3893         }
   3894 
   3895         case PVP_ENGINE_COMMAND_QUERY_UUID:
   3896         case PVP_ENGINE_COMMAND_QUERY_INTERFACE:
   3897         case PVP_ENGINE_COMMAND_GET_PLAYBACK_RANGE:
   3898         case PVP_ENGINE_COMMAND_GET_PLAYBACK_RATE:
   3899         case PVP_ENGINE_COMMAND_GET_PLAYBACK_MINMAX_RATE:
   3900         case PVP_ENGINE_COMMAND_GET_SDK_INFO:
   3901         case PVP_ENGINE_COMMAND_GET_SDK_MODULE_INFO:
   3902         case PVP_ENGINE_COMMAND_SET_LOG_APPENDER:
   3903         case PVP_ENGINE_COMMAND_REMOVE_LOG_APPENDER:
   3904         case PVP_ENGINE_COMMAND_SET_LOG_LEVEL:
   3905         case PVP_ENGINE_COMMAND_GET_LOG_LEVEL:
   3906         case PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS:
   3907         case PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE:
   3908         case PVP_ENGINE_COMMAND_ADD_DATA_SINK:
   3909         case PVP_ENGINE_COMMAND_GET_CURRENT_POSITION:
   3910         case PVP_ENGINE_COMMAND_START:
   3911         case PVP_ENGINE_COMMAND_REMOVE_DATA_SINK:
   3912         case PVP_ENGINE_COMMAND_REMOVE_DATA_SOURCE:
   3913         default:
   3914             // These commands should complete in one AO scheduling so there should be no need to cancel.
   3915             // CancelAll() is done so complete it
   3916             EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFSuccess);
   3917             break;
   3918     }
   3919 
   3920     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() Out"));
   3921 }
   3922 
   3923 
   3924 PVMFStatus PVPlayerEngine::DoCancelPendingNodeDatapathCommand()
   3925 {
   3926     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() In"));
   3927 
   3928     OSCL_ASSERT(iCurrentContextList.empty() == false);
   3929 
   3930     // Determine where the pending commands were issued to and then cancel them
   3931     int32 leavecode = 0;
   3932     iNumberCancelCmdPending = 0;
   3933     for (uint32 i = 0; i < iCurrentContextList.size(); ++i)
   3934     {
   3935         if (iCurrentContextList[i]->iNode)
   3936         {
   3937             if (iCurrentContextList[i]->iNode == iSourceNode)
   3938             {
   3939                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on source node"));
   3940                 leavecode = IssueNodeCancelCommand(iCurrentContextList[i], iSourceNodeSessionId, (OsclAny*) & iNumberCancelCmdPending);
   3941                 if (leavecode == 0)
   3942                 {
   3943                     ++iNumberCancelCmdPending;
   3944                 }
   3945                 else
   3946                 {
   3947                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3948                                     (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on source node did a leave"));
   3949                     FreeEngineContext(iCurrentContextList[i]);
   3950                 }
   3951             }
   3952             else if (iCurrentContextList[i]->iEngineDatapath != NULL)
   3953             {
   3954                 if (iCurrentContextList[i]->iNode == iCurrentContextList[i]->iEngineDatapath->iSinkNode)
   3955                 {
   3956                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on sink node"));
   3957                     leavecode = IssueNodeCancelCommand(iCurrentContextList[i], iCurrentContextList[i]->iEngineDatapath->iSinkNodeSessionId, (OsclAny*) & iNumberCancelCmdPending);
   3958                     if (leavecode == 0)
   3959                     {
   3960                         ++iNumberCancelCmdPending;
   3961                     }
   3962                     else
   3963                     {
   3964                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3965                                         (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on sink node did a leave"));
   3966                         FreeEngineContext(iCurrentContextList[i]);
   3967                     }
   3968                 }
   3969                 else if (iCurrentContextList[i]->iNode == iCurrentContextList[i]->iEngineDatapath->iDecNode)
   3970                 {
   3971                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on dec node"));
   3972                     leavecode = IssueNodeCancelCommand(iCurrentContextList[i], iCurrentContextList[i]->iEngineDatapath->iDecNodeSessionId, (OsclAny*) & iNumberCancelCmdPending);
   3973                     if (leavecode == 0)
   3974                     {
   3975                         ++iNumberCancelCmdPending;
   3976                     }
   3977                     else
   3978                     {
   3979                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   3980                                         (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on dec node did a leave"));
   3981                         FreeEngineContext(iCurrentContextList[i]);
   3982                     }
   3983                 }
   3984                 else
   3985                 {
   3986                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Unknown node type. Asserting"));
   3987                     OSCL_ASSERT(false);
   3988                 }
   3989             }
   3990             else
   3991             {
   3992                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Unknown node. Asserting"));
   3993                 OSCL_ASSERT(false);
   3994             }
   3995         }
   3996         else if (iCurrentContextList[i]->iDatapath != NULL)
   3997         {
   3998             if (iCurrentContextList[i]->iEngineDatapath != NULL)
   3999             {
   4000                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on datapath"));
   4001                 leavecode = IssueDatapathCancelCommand(iCurrentContextList[i], (OsclAny*) & iNumberCancelCmdPending);
   4002                 if (leavecode == 0)
   4003                 {
   4004                     ++iNumberCancelCmdPending;
   4005                 }
   4006             }
   4007             else
   4008             {
   4009                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Unknown datapath. Asserting"));
   4010                 OSCL_ASSERT(false);
   4011             }
   4012         }
   4013         else if (iCurrentContextList[i]->iCmdType == PVP_CMD_QUERYSOURCEFORMATTYPE)
   4014         {
   4015             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on recognizer"));
   4016             leavecode = IssueRecognizerRegistryCancel((OsclAny*) & iNumberCancelCmdPending);
   4017             if (leavecode == 0)
   4018             {
   4019                 ++iNumberCancelCmdPending;
   4020             }
   4021             else
   4022             {
   4023                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4024                                 (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on recognizer node did a leave"));
   4025                 FreeEngineContext(iCurrentContextList[i]);
   4026             }
   4027         }
   4028         else
   4029         {
   4030             // Either a node or datapath should be pending
   4031             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() No pending node or datapath. Asserting"));
   4032             OSCL_ASSERT(false);
   4033         }
   4034     }
   4035 
   4036     if (iNumberCancelCmdPending == 0)
   4037     {
   4038         // Cancel on the node / datapath failed so go to next step
   4039         // Note that we do not care about not being able to queue cancel since
   4040         // we are going to reset the components anyway
   4041         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on the node did a leave"));
   4042         RemoveDatapathContextFromList(); // remove left-over datapath contexts
   4043         return PVMFSuccess;
   4044     }
   4045     else
   4046     {
   4047         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() %d CancelAllCommands are pending", iNumberCancelCmdPending));
   4048     }
   4049 
   4050     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Out"));
   4051     return PVMFPending;
   4052 }
   4053 
   4054 PVMFStatus PVPlayerEngine::DoGetSDKInfo(PVPlayerEngineCommand& aCmd)
   4055 {
   4056     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetSDKInfo() In"));
   4057 
   4058     PVSDKInfo* sdkinfo = (PVSDKInfo*)(aCmd.GetParam(0).pOsclAny_value);
   4059     if (sdkinfo == NULL)
   4060     {
   4061         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetSDKInfo() Passed in parameter invalid."));
   4062         return PVMFErrArgument;
   4063     }
   4064 
   4065     // Set the SDK info to the ones defined in the header file pv_player_sdkinfo.h generated at build time
   4066     sdkinfo->iLabel = PVPLAYER_ENGINE_SDKINFO_LABEL;
   4067     sdkinfo->iDate = PVPLAYER_ENGINE_SDKINFO_DATE;
   4068 
   4069     EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFSuccess);
   4070 
   4071     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetSDKInfo() Out"));
   4072     return PVMFSuccess;
   4073 }
   4074 
   4075 
   4076 PVMFStatus PVPlayerEngine::DoSetLogAppender(PVPlayerEngineCommand& aCmd)
   4077 {
   4078     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogAppender() In"));
   4079 
   4080     char* tag = (char*)(aCmd.GetParam(0).pChar_value);
   4081     OsclSharedPtr<PVLoggerAppender>* appender = (OsclSharedPtr<PVLoggerAppender>*)(aCmd.GetParam(1).pOsclAny_value);
   4082 
   4083     if (tag == NULL || appender == NULL)
   4084     {
   4085         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogAppender() Passed in parameter invalid."));
   4086         return PVMFErrArgument;
   4087     }
   4088 
   4089     // Get the logger node based on the specified tag
   4090     PVLogger *rootnode = PVLogger::GetLoggerObject(tag);
   4091     if (rootnode == NULL)
   4092     {
   4093         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogAppender() Node specified by tag is invalid"));
   4094         return PVMFErrBadHandle;
   4095     }
   4096 
   4097     // Add the specified appender to this node
   4098     rootnode->AddAppender(*appender);
   4099 
   4100     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4101 
   4102 
   4103     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogAppender() Out"));
   4104     return PVMFSuccess;
   4105 }
   4106 
   4107 
   4108 PVMFStatus PVPlayerEngine::DoRemoveLogAppender(PVPlayerEngineCommand& aCmd)
   4109 {
   4110     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveLogAppender() In"));
   4111 
   4112     char* tag = (char*)(aCmd.GetParam(0).pChar_value);
   4113     OsclSharedPtr<PVLoggerAppender>* appender = (OsclSharedPtr<PVLoggerAppender>*)(aCmd.GetParam(1).pOsclAny_value);
   4114 
   4115     if (tag == NULL || appender == NULL)
   4116     {
   4117         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveLogAppender() Passed in parameter invalid."));
   4118         return PVMFErrArgument;
   4119     }
   4120 
   4121     // Get the logger node based on the specified tag
   4122     PVLogger *lognode = PVLogger::GetLoggerObject(tag);
   4123     if (lognode == NULL)
   4124     {
   4125         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveLogAppender() Node specified by tag is invalid"));
   4126         return PVMFErrBadHandle;
   4127     }
   4128 
   4129     // Remove the specified appender to this node
   4130     lognode->RemoveAppender(*appender);
   4131 
   4132     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4133 
   4134 
   4135     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveLogAppender() Out"));
   4136     return PVMFSuccess;
   4137 }
   4138 
   4139 
   4140 PVMFStatus PVPlayerEngine::DoSetLogLevel(PVPlayerEngineCommand& aCmd)
   4141 {
   4142     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogLevel() In"));
   4143 
   4144     char* tag = (char*)(aCmd.GetParam(0).pChar_value);
   4145     int32 level = aCmd.GetParam(1).int32_value;
   4146     bool subtree = aCmd.GetParam(2).bool_value;
   4147 
   4148     if (tag == NULL)
   4149     {
   4150         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogLevel() Passed in parameter invalid."));
   4151         return PVMFErrArgument;
   4152     }
   4153 
   4154     // Get the logger node based on the specified tag
   4155     PVLogger *lognode = PVLogger::GetLoggerObject(tag);
   4156     if (lognode == NULL)
   4157     {
   4158         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogLevel() Node specified by tag is invalid"));
   4159         return PVMFErrBadHandle;
   4160     }
   4161 
   4162     // Set the log level
   4163     if (subtree)
   4164     {
   4165         lognode->SetLogLevelAndPropagate(level);
   4166     }
   4167     else
   4168     {
   4169         lognode->SetLogLevel(level);
   4170     }
   4171 
   4172     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4173 
   4174 
   4175     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogLevel() Out"));
   4176     return PVMFSuccess;
   4177 }
   4178 
   4179 
   4180 PVMFStatus PVPlayerEngine::DoGetLogLevel(PVPlayerEngineCommand& aCmd)
   4181 {
   4182     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLogLevel() In"));
   4183 
   4184     char* tag = (char*)(aCmd.GetParam(0).pChar_value);
   4185     PVLogLevelInfo* levelinfo = (PVLogLevelInfo*)(aCmd.GetParam(1).pOsclAny_value);
   4186 
   4187     if (tag == NULL || levelinfo == NULL)
   4188     {
   4189         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetLogLevel() Passed in parameter invalid."));
   4190         return PVMFErrArgument;
   4191     }
   4192 
   4193     // Get the logger node based on the specified tag
   4194     PVLogger *lognode = PVLogger::GetLoggerObject(tag);
   4195     if (lognode == NULL)
   4196     {
   4197         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetLogLevel() Node specified by tag is invalid"));
   4198         return PVMFErrBadHandle;
   4199     }
   4200 
   4201     // Get the log level info
   4202     *levelinfo = lognode->GetLogLevel();
   4203 
   4204     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4205 
   4206     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLogLevel() Out"));
   4207     return PVMFSuccess;
   4208 }
   4209 
   4210 
   4211 PVMFStatus PVPlayerEngine::DoQueryUUID(PVPlayerEngineCommand& aCmd)
   4212 {
   4213     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryUUID() In"));
   4214 
   4215     PvmfMimeString* mimetype;
   4216     Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
   4217     bool exactmatch;
   4218 
   4219     mimetype = (PvmfMimeString*)(aCmd.GetParam(0).pOsclAny_value);
   4220     uuidvec = (Oscl_Vector<PVUuid, OsclMemAllocator>*)(aCmd.GetParam(1).pOsclAny_value);
   4221     exactmatch = aCmd.GetParam(2).bool_value;
   4222 
   4223     if (mimetype == NULL || uuidvec == NULL)
   4224     {
   4225         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoQueryUUID() Passed in parameter invalid."));
   4226         return PVMFErrArgument;
   4227     }
   4228 
   4229     int32 leavecode = 0;
   4230 
   4231     // For now just return all available extension interface UUID
   4232     OSCL_TRY(leavecode,
   4233              // Capability and config interface
   4234              uuidvec->push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID);
   4235              // License acquisition interface
   4236              uuidvec->push_back(PVPlayerLicenseAcquisitionInterfaceUuid);
   4237              // Track level info interface from source node
   4238              if (iSourceNodeTrackLevelInfoIF)
   4239 {
   4240     uuidvec->push_back(PVMF_TRACK_LEVEL_INFO_INTERFACE_UUID);
   4241     }
   4242             );
   4243     OSCL_FIRST_CATCH_ANY(leavecode,
   4244                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoQueryUUID() Leaved"));
   4245                          EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrNoMemory);
   4246                          PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryUUID() Out"));
   4247                          return PVMFSuccess;);
   4248 
   4249     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4250 
   4251     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryUUID() Out"));
   4252     return PVMFSuccess;
   4253 }
   4254 
   4255 
   4256 PVMFStatus PVPlayerEngine::DoQueryInterface(PVPlayerEngineCommand& aCmd)
   4257 {
   4258     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryInterface() In"));
   4259 
   4260     PVInterface** ifptr = (PVInterface**)(aCmd.GetParam(0).pOsclAny_value);
   4261     PVUuid uuid = aCmd.GetUuid();
   4262     if (ifptr == NULL)
   4263     {
   4264         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoQueryInterface() Passed in parameter invalid."));
   4265         return PVMFErrArgument;
   4266     }
   4267 
   4268     PVMFStatus cmdstatus = PVMFSuccess;
   4269     if (queryInterface(uuid, *ifptr) == false)
   4270     {
   4271         cmdstatus = PVMFErrNotSupported;
   4272     }
   4273     else
   4274     {
   4275         (*ifptr)->addRef();
   4276     }
   4277 
   4278     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), cmdstatus);
   4279 
   4280     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryInterface() Out"));
   4281     return PVMFSuccess;
   4282 }
   4283 
   4284 
   4285 PVMFStatus PVPlayerEngine::DoGetPVPlayerState(PVPlayerEngineCommand& aCmd, bool aSyncCmd)
   4286 {
   4287     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPVPlayerState() In"));
   4288 
   4289     PVPlayerState* state = (PVPlayerState*)(aCmd.GetParam(0).pOsclAny_value);
   4290     if (state == NULL)
   4291     {
   4292         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPVPlayerState() Passed in parameter invalid."));
   4293         return PVMFErrArgument;
   4294     }
   4295 
   4296     // Get player state using internal function
   4297     *state = GetPVPlayerState();
   4298 
   4299     if (!aSyncCmd)
   4300     {
   4301         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4302     }
   4303 
   4304     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPVPlayerState() Out"));
   4305     return PVMFSuccess;
   4306 }
   4307 
   4308 
   4309 PVMFStatus PVPlayerEngine::DoAddDataSource(PVPlayerEngineCommand& aCmd)
   4310 {
   4311     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   4312                     (0, "PVPlayerEngine::DoAddDataSource() Tick=%d", OsclTickCount::TickCount()));
   4313 
   4314     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSource() In"));
   4315 
   4316     if (GetPVPlayerState() != PVP_STATE_IDLE)
   4317     {
   4318         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() Wrong engine state"));
   4319         return PVMFErrInvalidState;
   4320     }
   4321 
   4322     if (aCmd.GetParam(0).pOsclAny_value == NULL)
   4323     {
   4324         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() Passed in parameter invalid."));
   4325         return PVMFErrArgument;
   4326     }
   4327 
   4328     // Save the data source
   4329     iDataSource = (PVPlayerDataSource*)(aCmd.GetParam(0).pOsclAny_value);
   4330 
   4331     // (mg) For rollover reset to first available alternate
   4332     iAlternateSrcFormatIndex = 0;
   4333     iDataReadySent = false;
   4334 
   4335     // Check the source format and do a recognize if unknown
   4336     PVMFStatus retval = PVMFSuccess;
   4337     iSourceFormatType = iDataSource->GetDataSourceFormatType();
   4338 
   4339     if (iSourceFormatType == PVMF_MIME_FORMAT_UNKNOWN)
   4340     {
   4341         retval = DoQuerySourceFormatType(aCmd.GetCmdId(), aCmd.GetContext());
   4342     }
   4343     else
   4344     {
   4345         if (iSourceFormatType == PVMF_MIME_DATA_SOURCE_UNKNOWN_URL)
   4346         {
   4347             retval = SetupDataSourceForUnknownURLAccess();
   4348             if (retval != PVMFSuccess)
   4349             {
   4350                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSource() - SetupDataSourceForUnknownURLAccess Failed"));
   4351                 return retval;
   4352             }
   4353         }
   4354 
   4355         // Start the source node creation and setup sequence
   4356         retval = DoSetupSourceNode(aCmd.GetCmdId(), aCmd.GetContext());
   4357 
   4358         if (retval != PVMFSuccess)
   4359         {
   4360             bool ehPending = CheckForPendingErrorHandlingCmd();
   4361             if (ehPending)
   4362             {
   4363                 // there should be no error handling queued.
   4364                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() Already EH pending, should never happen"));
   4365                 return PVMFPending;
   4366             }
   4367             // Queue up Error Handling
   4368             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() DoSetupSourceNode failed, Add EH command"));
   4369             iCommandCompleteStatusInErrorHandling = retval;
   4370             iCommandCompleteErrMsgInErrorHandling = NULL;
   4371             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
   4372             return PVMFPending;
   4373         }
   4374     }
   4375 
   4376     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSource() Out"));
   4377     return retval;
   4378 
   4379 }
   4380 
   4381 
   4382 PVMFStatus PVPlayerEngine::DoQuerySourceFormatType(PVCommandId aCmdId, OsclAny* aCmdContext)
   4383 {
   4384     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   4385                     (0, "PVPlayerEngine::DoQuerySourceFormatType() Tick=%d", OsclTickCount::TickCount()));
   4386 
   4387     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQuerySourceFormatType() In"));
   4388 
   4389     // Use the recognizer if the source format type is unknown
   4390     OSCL_ASSERT(iDataSource != NULL);
   4391     PVPlayerEngineContext* context = AllocateEngineContext(NULL, NULL, NULL, aCmdId, aCmdContext, PVP_CMD_QUERYSOURCEFORMATTYPE);
   4392     PVMFStatus retval = PVMFSuccess;
   4393     int32 leavecode = 0;
   4394 
   4395     OsclAny * opaqueData = iDataSource->GetDataSourceContextData();
   4396     PVInterface* pvInterface = OSCL_STATIC_CAST(PVInterface*, opaqueData);
   4397     PVInterface* SourceContextData = NULL;
   4398     PVUuid SourceContextDataUuid(PVMF_SOURCE_CONTEXT_DATA_UUID);
   4399     PVMFCPMPluginAccessInterfaceFactory * DataStreamDataFactory = NULL;
   4400 
   4401     if (pvInterface != NULL && pvInterface->queryInterface(SourceContextDataUuid, SourceContextData))
   4402     {
   4403         PVMFSourceContextData * aSourceContextData = OSCL_STATIC_CAST(PVMFSourceContextData*, SourceContextData);
   4404         PVMFSourceContextDataCommon * aSourceContextDataCommon = aSourceContextData->CommonData();
   4405         if (aSourceContextDataCommon)
   4406         {
   4407             DataStreamDataFactory = aSourceContextDataCommon->iRecognizerDataStreamFactory;
   4408         }
   4409     }
   4410 
   4411     if (DataStreamDataFactory)
   4412     {
   4413         OSCL_TRY(leavecode, retval = iPlayerRecognizerRegistry.QueryFormatType(DataStreamDataFactory, *this, (OsclAny*) context));
   4414         OSCL_FIRST_CATCH_ANY(leavecode,
   4415                              FreeEngineContext(context);
   4416                              return PVMFErrNotSupported;
   4417                             );
   4418     }
   4419     else
   4420     {
   4421         OSCL_TRY(leavecode, retval = iPlayerRecognizerRegistry.QueryFormatType(iDataSource->GetDataSourceURL(), *this, (OsclAny*) context));
   4422         OSCL_FIRST_CATCH_ANY(leavecode,
   4423                              FreeEngineContext(context);
   4424                              return PVMFErrNotSupported;
   4425                             );
   4426     }
   4427 
   4428     if (retval != PVMFSuccess)
   4429     {
   4430         FreeEngineContext(context);
   4431     }
   4432 
   4433     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQuerySourceFormatType() Out"));
   4434     return retval;
   4435 }
   4436 
   4437 
   4438 PVMFStatus PVPlayerEngine::DoSetupSourceNode(PVCommandId aCmdId, OsclAny* aCmdContext)
   4439 {
   4440     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   4441                     (0, "PVPlayerEngine::DoSetupSourceNode() Tick=%d", OsclTickCount::TickCount()));
   4442 
   4443     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetupSourceNode() In"));
   4444 
   4445     OSCL_ASSERT(iDataSource != NULL);
   4446 
   4447     if (iSourceNode == NULL)
   4448     {
   4449         PVMFFormatType outputformattype = PVMF_MIME_FORMAT_UNKNOWN ;
   4450 
   4451         Oscl_Vector<PVUuid, OsclMemAllocator> foundUuids;
   4452         // Query the node registry
   4453         if (iPlayerNodeRegistry.QueryRegistry(iSourceFormatType, outputformattype, foundUuids) == PVMFSuccess)
   4454         {
   4455             if (foundUuids.empty())
   4456             {
   4457                 // No matching node found
   4458                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4459                                 (0, "PVPlayerEngine::DoSetupSourceNode() Query Regsitry successful, No matching source node found."));
   4460                 return PVMFErrNotSupported;
   4461             }
   4462 
   4463             int32 leavecode = 0;
   4464             OSCL_TRY(leavecode, iSourceNode = iPlayerNodeRegistry.CreateNode(foundUuids[0], true));
   4465             OSCL_FIRST_CATCH_ANY(leavecode,
   4466                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupDecNode() Error in creating SourceNode"));
   4467                                  return PVMFFailure;);
   4468 
   4469             iNodeUuids.push_back(PVPlayerEngineUuidNodeMapping(foundUuids[0], iSourceNode));
   4470 
   4471             if (iSourceNode == NULL)
   4472             {
   4473                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() Source node create failed"));
   4474                 return PVMFErrNoMemory;
   4475             }
   4476         }
   4477         else
   4478         {
   4479             // Registry query failed
   4480             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() Registry query for source node failed"));
   4481             return PVMFErrNotSupported;
   4482         }
   4483     }
   4484 
   4485     if (iSourceNode->ThreadLogon() != PVMFSuccess)
   4486     {
   4487         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() ThreadLogon() on the source node failed"));
   4488         OSCL_ASSERT(false);
   4489         return PVMFFailure;
   4490     }
   4491 
   4492     PVMFNodeSessionInfo nodesessioninfo(this, this, (OsclAny*)iSourceNode, this, (OsclAny*)iSourceNode);
   4493     int32 leavecode = 0;
   4494     OSCL_TRY(leavecode, iSourceNodeSessionId = iSourceNode->Connect(nodesessioninfo));
   4495     OSCL_FIRST_CATCH_ANY(leavecode,
   4496                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() Connect on iSourceNode did a leave!"));
   4497                          OSCL_ASSERT(false);
   4498                          return PVMFFailure);
   4499 
   4500     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryInitIF);
   4501 
   4502     PVUuid sourceinituuid = PVMF_DATA_SOURCE_INIT_INTERFACE_UUID;
   4503     leavecode = 0;
   4504     PVMFCommandId cmdid = -1;
   4505     iSourceNodePVInterfaceInit = NULL;
   4506     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, sourceinituuid, iSourceNodePVInterfaceInit, (OsclAny*)context));
   4507     OSCL_FIRST_CATCH_ANY(leavecode,
   4508                          iSourceNodePVInterfaceInit = NULL;
   4509                          FreeEngineContext(context);
   4510                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() QueryInterface on iSourceNode did a leave!"));
   4511                          return PVMFFailure);
   4512 
   4513     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetupSourceNode() Out"));
   4514     return PVMFSuccess;
   4515 }
   4516 
   4517 
   4518 PVMFStatus PVPlayerEngine::DoSourceNodeQueryTrackSelIF(PVCommandId aCmdId, OsclAny* aCmdContext)
   4519 {
   4520     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   4521                     (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Tick=%d", OsclTickCount::TickCount()));
   4522 
   4523     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() In"));
   4524 
   4525     int32 leavecode = 0;
   4526 
   4527     if (iDataSource->GetDataSourceType() == PVP_DATASRCTYPE_URL)
   4528     {
   4529         // Setup the source node via the initialization IF
   4530         OSCL_ASSERT(iSourceFormatType != PVMF_MIME_FORMAT_UNKNOWN);
   4531 
   4532         OSCL_wHeapString<OsclMemAllocator> sourceURL;
   4533         // In case the URL starts with file:// skip it
   4534         OSCL_wStackString<8> fileScheme(_STRLIT_WCHAR("file"));
   4535         OSCL_wStackString<8> schemeDelimiter(_STRLIT_WCHAR("://"));
   4536         const oscl_wchar* actualURL = NULL;
   4537 
   4538         if (oscl_strncmp(fileScheme.get_cstr(), iDataSource->GetDataSourceURL().get_cstr(), 4) == 0)
   4539         {
   4540             actualURL = oscl_strstr(iDataSource->GetDataSourceURL().get_cstr(), schemeDelimiter.get_cstr());
   4541             if (actualURL == NULL)
   4542             {
   4543                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Unable to skip over file://"));
   4544                 return PVMFErrArgument;
   4545             }
   4546             //skip over ://
   4547             actualURL += schemeDelimiter.get_size();
   4548             sourceURL += actualURL;
   4549         }
   4550         else
   4551         {
   4552             sourceURL += iDataSource->GetDataSourceURL().get_cstr();
   4553         }
   4554 
   4555         PVMFStatus retval = iSourceNodeInitIF->SetSourceInitializationData(sourceURL, iSourceFormatType, iDataSource->GetDataSourceContextData());
   4556         if (retval != PVMFSuccess)
   4557         {
   4558             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() SetSourceInitializationData failed"));
   4559             return PVMFFailure;
   4560         }
   4561         // Set Playback Clock
   4562         retval = iSourceNodeInitIF->SetClientPlayBackClock(&iPlaybackClock);
   4563         if (retval != PVMFSuccess)
   4564         {
   4565             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() SetClientPlayBackClock failed!"));
   4566             return PVMFFailure;
   4567         }
   4568     }
   4569     else
   4570     {
   4571         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Data source type not supported yet so asserting"));
   4572         OSCL_ASSERT(false);
   4573         return PVMFFailure;
   4574     }
   4575 
   4576     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryTrackSelIF);
   4577 
   4578     // Query the source node for the track selection IF
   4579     PVUuid trackseluuid = PVMF_TRACK_SELECTION_INTERFACE_UUID;
   4580     PVMFCommandId cmdid = -1;
   4581     leavecode = 0;
   4582     iSourceNodePVInterfaceTrackSel = NULL;
   4583     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, trackseluuid, iSourceNodePVInterfaceTrackSel, (OsclAny*)context));
   4584     OSCL_FIRST_CATCH_ANY(leavecode,
   4585                          iSourceNodePVInterfaceTrackSel = NULL;
   4586                          FreeEngineContext(context);
   4587                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() QueryInterface on iSourceNode did a leave!"));
   4588                          return PVMFFailure);
   4589 
   4590     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Out"));
   4591     return PVMFSuccess;
   4592 }
   4593 
   4594 
   4595 PVMFStatus PVPlayerEngine::DoSourceNodeQueryInterfaceOptional(PVCommandId aCmdId, OsclAny* aCmdContext)
   4596 {
   4597     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   4598                     (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
   4599 
   4600     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() In"));
   4601 
   4602     PVPlayerEngineContext* context = NULL;
   4603     PVMFCommandId cmdid = -1;
   4604     int32 leavecode = 0;
   4605 
   4606     iNumPendingNodeCmd = 0;
   4607 
   4608     // Query for Track Level Info IF
   4609     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryTrackLevelInfoIF);
   4610     PVUuid tracklevelinfouuid = PVMF_TRACK_LEVEL_INFO_INTERFACE_UUID;
   4611     cmdid = -1;
   4612     leavecode = 0;
   4613     iSourceNodePVInterfaceTrackLevelInfo = NULL;
   4614     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, tracklevelinfouuid, iSourceNodePVInterfaceTrackLevelInfo, (OsclAny*)context));
   4615     if (leavecode)
   4616     {
   4617         iSourceNodePVInterfaceTrackLevelInfo = NULL;
   4618         FreeEngineContext(context);
   4619         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4620     }
   4621     else
   4622     {
   4623         ++iNumPendingNodeCmd;
   4624     }
   4625 
   4626     // Query for Playback Control IF
   4627     context = NULL;
   4628     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryPBCtrlIF);
   4629     PVUuid pbctrluuid = PvmfDataSourcePlaybackControlUuid;
   4630     cmdid = -1;
   4631     leavecode = 0;
   4632     iSourceNodePVInterfacePBCtrl = NULL;
   4633     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, pbctrluuid, iSourceNodePVInterfacePBCtrl, (OsclAny*)context));
   4634     if (leavecode)
   4635     {
   4636         iSourceNodePVInterfacePBCtrl = NULL;
   4637         FreeEngineContext(context);
   4638         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4639     }
   4640     else
   4641     {
   4642         ++iNumPendingNodeCmd;
   4643     }
   4644 
   4645     // Query for direction control IF
   4646     context = NULL;
   4647     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryDirCtrlIF);
   4648     PVUuid dirctrluuid = PvmfDataSourceDirectionControlUuid;
   4649     cmdid = -1;
   4650     leavecode = 0;
   4651     iSourceNodePVInterfaceDirCtrl = NULL;
   4652     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, dirctrluuid, iSourceNodePVInterfaceDirCtrl, (OsclAny*)context));
   4653     if (leavecode)
   4654     {
   4655         iSourceNodePVInterfaceDirCtrl = NULL;
   4656         FreeEngineContext(context);
   4657         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4658     }
   4659     else
   4660     {
   4661         ++iNumPendingNodeCmd;
   4662     }
   4663 
   4664     // Query for Metadata IF
   4665     context = NULL;
   4666     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryMetadataIF);
   4667     PVUuid metadatauuid = KPVMFMetadataExtensionUuid;
   4668     cmdid = -1;
   4669     leavecode = 0;
   4670     iSourceNodePVInterfaceMetadataExt = NULL;
   4671     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, metadatauuid, iSourceNodePVInterfaceMetadataExt, (OsclAny*)context));
   4672     if (leavecode)
   4673     {
   4674         iSourceNodePVInterfaceMetadataExt = NULL;
   4675         FreeEngineContext(context);
   4676         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4677     }
   4678     else
   4679     {
   4680         ++iNumPendingNodeCmd;
   4681     }
   4682 
   4683     // Query for Cap-Config IF
   4684     context = NULL;
   4685     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryCapConfigIF);
   4686     PVUuid capconfiguuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID;
   4687     cmdid = -1;
   4688     leavecode = 0;
   4689     iSourceNodePVInterfaceCapConfig = NULL;
   4690     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, capconfiguuid, iSourceNodePVInterfaceCapConfig, (OsclAny*)context));
   4691     if (leavecode)
   4692     {
   4693         iSourceNodePVInterfaceCapConfig = NULL;
   4694         FreeEngineContext(context);
   4695         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4696     }
   4697     else
   4698     {
   4699         ++iNumPendingNodeCmd;
   4700     }
   4701 
   4702     // Query for CPM License interface
   4703     context = NULL;
   4704     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryCPMLicenseIF);
   4705     PVUuid licUuid = PVMFCPMPluginLicenseInterfaceUuid;
   4706     cmdid = -1;
   4707     leavecode = 0;
   4708     iSourceNodePVInterfaceCPMLicense = NULL;
   4709     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, licUuid, iSourceNodePVInterfaceCPMLicense, (OsclAny*)context));
   4710     if (leavecode)
   4711     {
   4712         iSourceNodePVInterfaceCPMLicense = NULL;
   4713         FreeEngineContext(context);
   4714         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4715     }
   4716     else
   4717     {
   4718         ++iNumPendingNodeCmd;
   4719     }
   4720 
   4721     // Query for source node registry init extension IF
   4722     context = NULL;
   4723     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQuerySrcNodeRegInitIF);
   4724     PVUuid regInitUuid = PVMF_DATA_SOURCE_NODE_REGISRTY_INIT_INTERFACE_UUID;
   4725     cmdid = -1;
   4726     leavecode = 0;
   4727     iSourceNodePVInterfaceRegInit = NULL;
   4728     OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, regInitUuid, iSourceNodePVInterfaceRegInit, (OsclAny*)context));
   4729     if (leavecode)
   4730     {
   4731         iSourceNodePVInterfaceRegInit = NULL;
   4732         FreeEngineContext(context);
   4733         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
   4734     }
   4735     else
   4736     {
   4737         ++iNumPendingNodeCmd;
   4738     }
   4739 
   4740     if (iNumPendingNodeCmd > 0)
   4741     {
   4742         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() Out"));
   4743         return PVMFSuccess;
   4744     }
   4745     else
   4746     {
   4747         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() Out No pending QueryInterface() on source node"));
   4748         return PVMFFailure;
   4749     }
   4750 }
   4751 
   4752 PVMFStatus PVPlayerEngine::DoGetMetadataKey(PVPlayerEngineCommand& aCmd)
   4753 {
   4754     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   4755                     (0, "PVPlayerEngine::DoGetMetadataKey() Tick=%d", OsclTickCount::TickCount()));
   4756 
   4757     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataKey() In"));
   4758 
   4759     if (GetPVPlayerState() == PVP_STATE_ERROR)
   4760     {
   4761         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataKey() Wrong engine state."));
   4762         return PVMFFailure;
   4763     }
   4764 
   4765     iGetMetadataKeysParam.iKeyList = (PVPMetadataList*)(aCmd.GetParam(0).pOsclAny_value);
   4766     iGetMetadataKeysParam.iStartingKeyIndex = aCmd.GetParam(1).int32_value;
   4767     iGetMetadataKeysParam.iMaxKeyEntries = aCmd.GetParam(2).int32_value;
   4768     iGetMetadataKeysParam.iQueryKey = aCmd.GetParam(3).pChar_value;
   4769 
   4770     if (iGetMetadataKeysParam.iKeyList == NULL)
   4771     {
   4772         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataKey() Passed in parameter invalid."));
   4773         return PVMFErrArgument;
   4774     }
   4775 
   4776     if (iGetMetadataKeysParam.iMaxKeyEntries < -1 || iGetMetadataKeysParam.iMaxKeyEntries == 0 || iGetMetadataKeysParam.iStartingKeyIndex < 0)
   4777     {
   4778         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataKey() Passed in parameter invalid."));
   4779         return PVMFErrArgument;
   4780     }
   4781 
   4782     // Determine which node's metadata interface to start the retrieval based on the starting index
   4783     uint32 i = 0;
   4784     int32 totalnumkey = 0;
   4785     uint32 nodestartindex = 0;
   4786     while (i < iMetadataIFList.size())
   4787     {
   4788         int32 numkey = iMetadataIFList[i].iInterface->GetNumMetadataKeys(iGetMetadataKeysParam.iQueryKey);
   4789         if (iGetMetadataKeysParam.iStartingKeyIndex < (totalnumkey + numkey))
   4790         {
   4791             // Found the node to start the key retrieval
   4792             // Determine the start index for this node
   4793             nodestartindex = iGetMetadataKeysParam.iStartingKeyIndex - totalnumkey;
   4794             break;
   4795         }
   4796         else
   4797         {
   4798             // Keep checking
   4799             totalnumkey += numkey;
   4800             ++i;
   4801         }
   4802     }
   4803 
   4804     // Check if the search succeeded
   4805     if (i == iMetadataIFList.size() || iMetadataIFList.size() == 0)
   4806     {
   4807         // Starting index is too large or there is no metadata interface available
   4808         return PVMFErrArgument;
   4809     }
   4810 
   4811     // Retrieve the metadata key from the first node
   4812     PVPlayerEngineContext* context = AllocateEngineContext(iMetadataIFList[i].iEngineDatapath, iMetadataIFList[i].iNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_GetNodeMetadataKey);
   4813     PVMFMetadataExtensionInterface* metadataif = iMetadataIFList[i].iInterface;
   4814     PVMFSessionId sessionid = iMetadataIFList[i].iSessionId;
   4815     PVMFCommandId cmdid = -1;
   4816     cmdid = metadataif->GetNodeMetadataKeys(sessionid,
   4817                                             *(iGetMetadataKeysParam.iKeyList),
   4818                                             nodestartindex,
   4819                                             iGetMetadataKeysParam.iMaxKeyEntries,
   4820                                             iGetMetadataKeysParam.iQueryKey,
   4821                                             (OsclAny*)context);
   4822     if (cmdid == -1)
   4823     {
   4824         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4825                         (0, "PVPlayerEngine::DoGetMetadataKey() GetNodeMetadataKeys failed"));
   4826         return PVMFFailure;
   4827     }
   4828 
   4829     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataKey() Out"));
   4830 
   4831     // Save the current metadata value retrieval status
   4832     iGetMetadataKeysParam.iCurrentInterfaceIndex = i;
   4833     iGetMetadataKeysParam.iNumKeyEntriesToFill = iGetMetadataKeysParam.iMaxKeyEntries;
   4834     iGetMetadataKeysParam.iNumKeyEntriesInList = iGetMetadataKeysParam.iKeyList->size();
   4835 
   4836     return PVMFSuccess;
   4837 }
   4838 
   4839 
   4840 PVMFStatus PVPlayerEngine::DoGetMetadataValue(PVPlayerEngineCommand& aCmd)
   4841 {
   4842     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   4843                     (0, "PVPlayerEngine::DoGetMetadataValue() Tick=%d", OsclTickCount::TickCount()));
   4844 
   4845     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataValue() In"));
   4846 
   4847     if (GetPVPlayerState() == PVP_STATE_ERROR)
   4848     {
   4849         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataValue() Wrong engine state"));
   4850         return PVMFErrInvalidState;
   4851     }
   4852 
   4853     if (iReleaseMetadataValuesPending)
   4854     {
   4855         // App has called GetMetadataValues without calling ReleaseMetadata values on previous list. Wrong
   4856         // usage. Failure needs to be returned in this case.
   4857         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4858                         (0, "PVPlayerEngine::GetMetadataValues() Wrong usage, called again without releasing earlier metadata list"));
   4859         return PVMFErrReleaseMetadataValueNotDone;
   4860     }
   4861 
   4862     iGetMetadataValuesParam.iKeyList = (PVPMetadataList*)(aCmd.GetParam(0).pOsclAny_value);
   4863     iGetMetadataValuesParam.iStartingValueIndex = aCmd.GetParam(1).int32_value;
   4864     iGetMetadataValuesParam.iMaxValueEntries = aCmd.GetParam(2).int32_value;
   4865     iGetMetadataValuesParam.iNumAvailableValues = (int32*)(aCmd.GetParam(3).pOsclAny_value);
   4866     iGetMetadataValuesParam.iValueList = (Oscl_Vector<PvmiKvp, OsclMemAllocator>*)(aCmd.GetParam(4).pOsclAny_value);
   4867     iMetadataValuesCopiedInCallBack = aCmd.GetParam(5).bool_value;
   4868 
   4869     if (iGetMetadataValuesParam.iKeyList == NULL || iGetMetadataValuesParam.iValueList == NULL || iGetMetadataValuesParam.iNumAvailableValues == NULL)
   4870     {
   4871         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataValue() Passed in parameter invalid."));
   4872         return PVMFErrArgument;
   4873     }
   4874 
   4875     if (iGetMetadataValuesParam.iMaxValueEntries < -1 || iGetMetadataValuesParam.iMaxValueEntries == 0 || iGetMetadataValuesParam.iStartingValueIndex < 0)
   4876     {
   4877         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataValue() Passed in parameter invalid."));
   4878         return PVMFErrArgument;
   4879     }
   4880 
   4881     // Determine which node's metadata interface to start the retrieval based on the starting index
   4882     uint32 i = 0;
   4883     int32 totalnumvalue = 0;
   4884     uint32 nodestartindex = 0;
   4885     while (i < iMetadataIFList.size())
   4886     {
   4887         int32 numvalue = iMetadataIFList[i].iInterface->GetNumMetadataValues(*(iGetMetadataValuesParam.iKeyList));
   4888         if (iGetMetadataValuesParam.iStartingValueIndex < (totalnumvalue + numvalue))
   4889         {
   4890             // Found the node to start the value retrieval
   4891             // Determine the start index for this node
   4892             nodestartindex = iGetMetadataValuesParam.iStartingValueIndex - totalnumvalue;
   4893             // Save the number of available values so far
   4894             *(iGetMetadataValuesParam.iNumAvailableValues) = totalnumvalue + numvalue;
   4895             break;
   4896         }
   4897         else
   4898         {
   4899             // Keep checking
   4900             totalnumvalue += numvalue;
   4901             ++i;
   4902         }
   4903     }
   4904 
   4905     // Check if the search succeeded
   4906     if (i == iMetadataIFList.size() || iMetadataIFList.size() == 0)
   4907     {
   4908         // Starting index is too large or there is no metadata interface available
   4909         return PVMFErrArgument;
   4910     }
   4911 
   4912     // Retrieve the metadata value from the first node
   4913     PVPlayerEngineContext* context = AllocateEngineContext(iMetadataIFList[i].iEngineDatapath, iMetadataIFList[i].iNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_GetNodeMetadataValue);
   4914     PVMFMetadataExtensionInterface* metadataif = iMetadataIFList[i].iInterface;
   4915     PVMFSessionId sessionid = iMetadataIFList[i].iSessionId;
   4916     PVMFCommandId cmdid = -1;
   4917     cmdid = metadataif->GetNodeMetadataValues(sessionid,
   4918             *(iGetMetadataValuesParam.iKeyList),
   4919             *(iGetMetadataValuesParam.iValueList),
   4920             nodestartindex,
   4921             iGetMetadataValuesParam.iMaxValueEntries,
   4922             (OsclAny*)context);
   4923 
   4924     if (cmdid == -1)
   4925     {
   4926         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   4927                         (0, "PVPlayerEngine::DoGetMetadataValue() GetNodeMetadataValues failed"));
   4928         return PVMFFailure;
   4929     }
   4930 
   4931     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataValue() Out"));
   4932 
   4933     // Save the current metadata value retrieval status
   4934     iGetMetadataValuesParam.iCurrentInterfaceIndex = i;
   4935     iGetMetadataValuesParam.iNumValueEntriesToFill = iGetMetadataValuesParam.iMaxValueEntries;
   4936     iGetMetadataValuesParam.iNumValueEntriesInList = iGetMetadataValuesParam.iValueList->size();
   4937 
   4938     return PVMFSuccess;
   4939 }
   4940 
   4941 PVMFStatus PVPlayerEngine::DoReleaseMetadataValues(PVPlayerEngineCommand& aCmd)
   4942 {
   4943     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   4944                     (0, "PVPlayerEngine::DoReleaseMetadataValues() Tick=%d", OsclTickCount::TickCount()));
   4945 
   4946     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReleaseMetadataValues() In"));
   4947 
   4948     if (GetPVPlayerState() == PVP_STATE_ERROR ||
   4949             GetPVPlayerState() == PVP_STATE_IDLE)
   4950     {
   4951         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoReleaseMetadataValues() Wrong engine state"));
   4952         return PVMFErrInvalidState;
   4953     }
   4954 
   4955     iGetMetadataValuesParam.iValueList = (Oscl_Vector<PvmiKvp, OsclMemAllocator>*)(aCmd.GetParam(0).pOsclAny_value);
   4956 
   4957     if (iGetMetadataValuesParam.iValueList == NULL)
   4958     {
   4959         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoReleaseMetadataValues() Passed in parameter invalid."));
   4960         return PVMFErrArgument;
   4961     }
   4962 
   4963     // Release the memory allocated for the metadata values
   4964     while (iMetadataValueReleaseList.empty() == false)
   4965     {
   4966         PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
   4967         OSCL_ASSERT(mdif != NULL);
   4968         mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
   4969         iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
   4970     }
   4971 
   4972     iReleaseMetadataValuesPending = false;
   4973 
   4974     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4975 
   4976     return PVMFSuccess;
   4977 }
   4978 
   4979 PVMFStatus PVPlayerEngine::DoInit(PVPlayerEngineCommand& aCmd)
   4980 {
   4981     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   4982                     (0, "PVPlayerEngine::DoInit() Tick=%d", OsclTickCount::TickCount()));
   4983 
   4984     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoInit() In"));
   4985 
   4986     if (GetPVPlayerState() == PVP_STATE_INITIALIZED)
   4987     {
   4988         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() Engine already in Initialized State"));
   4989         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   4990         return PVMFSuccess;
   4991     }
   4992 
   4993     if ((GetPVPlayerState() != PVP_STATE_IDLE) || (iSourceNode == NULL))
   4994     {
   4995         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() Wrong engine state"));
   4996         return PVMFErrInvalidState;
   4997     }
   4998 
   4999     iRollOverState = RollOverStateIdle;
   5000 
   5001     PVMFStatus retval = DoSourceNodeInit(aCmd.GetCmdId(), aCmd.GetContext());
   5002 
   5003     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoInit() Out"));
   5004 
   5005     if (retval == PVMFSuccess)
   5006     {
   5007         SetEngineState(PVP_ENGINE_STATE_INITIALIZING);
   5008         return PVMFSuccess;
   5009     }
   5010     else
   5011     {
   5012         bool ehPending = CheckForPendingErrorHandlingCmd();
   5013         if (ehPending)
   5014         {
   5015             // there should be no error handling queued.
   5016             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() Already EH pending, should never happen"));
   5017             return PVMFPending;
   5018         }
   5019         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() DoSourceNodeInit failed, Add EH command"));
   5020         iCommandCompleteStatusInErrorHandling = retval;
   5021         iCommandCompleteErrMsgInErrorHandling = NULL;
   5022         AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   5023         return PVMFPending;
   5024     }
   5025 }
   5026 
   5027 
   5028 PVMFStatus PVPlayerEngine::DoSourceNodeInit(PVCommandId aCmdId, OsclAny* aCmdContext)
   5029 {
   5030     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   5031                     (0, "PVPlayerEngine::DoSourceNodeInit() Tick=%d", OsclTickCount::TickCount()));
   5032 
   5033     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeInit() In"));
   5034 
   5035     OSCL_ASSERT(iSourceNode != NULL);
   5036 
   5037     int32 leavecode = 0;
   5038 
   5039     // Initialize the source node
   5040     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeInit);
   5041 
   5042     leavecode = 0;
   5043     PVMFCommandId cmdid = -1;
   5044     OSCL_TRY(leavecode, cmdid = iSourceNode->Init(iSourceNodeSessionId, (OsclAny*)context));
   5045     OSCL_FIRST_CATCH_ANY(leavecode,
   5046                          FreeEngineContext(context);
   5047                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeInit() Init on iSourceNode did a leave!"));
   5048                          return PVMFFailure);
   5049 
   5050     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeInit() Out"));
   5051 
   5052     return PVMFSuccess;
   5053 }
   5054 
   5055 
   5056 PVMFStatus PVPlayerEngine::DoSourceNodeGetDurationValue(PVCommandId aCmdId, OsclAny* aCmdContext)
   5057 {
   5058     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetDurationValue() In"));
   5059 
   5060 
   5061     // Create a key list with just duration key
   5062     iSourceDurationKeyList.clear();
   5063     OSCL_HeapString<OsclMemAllocator> tmpstr = _STRLIT_CHAR("duration");
   5064     iSourceDurationKeyList.push_back(tmpstr);
   5065     // Clear the value list
   5066     iSourceDurationValueList.clear();
   5067 
   5068     if (iSourceNodeMetadataExtIF == NULL)
   5069     {
   5070         return PVMFErrArgument;
   5071     }
   5072 
   5073     // Call GetNodeMetadataValues on the source node to retrieve duration
   5074     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeGetDurationValue);
   5075 
   5076     int32 leavecode = 0;
   5077     PVMFCommandId cmdid = -1;
   5078     OSCL_TRY(leavecode, cmdid = iSourceNodeMetadataExtIF->GetNodeMetadataValues(iSourceNodeSessionId,
   5079                                 iSourceDurationKeyList,
   5080                                 iSourceDurationValueList,
   5081                                 0 /*starting index*/, 1 /*max entries*/, (OsclAny*)context));
   5082     OSCL_FIRST_CATCH_ANY(leavecode,
   5083                          FreeEngineContext(context);
   5084                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeGetDurationValue() GetNodeMetadataValues on iSourceNode did a leave!"));
   5085                          return PVMFFailure);
   5086 
   5087     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetDurationValue() Out"));
   5088     return PVMFSuccess;
   5089 }
   5090 
   5091 PVMFStatus PVPlayerEngine::DoSourceNodeRollOver(PVCommandId aCmdId, OsclAny* aCmdContext)
   5092 {
   5093     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeRollOver() In"));
   5094     /* Clean up any exisiting source node */
   5095     DoSourceNodeCleanup();
   5096 
   5097     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeRollOver() DoSourceNodeCleanup Complete"));
   5098     if (CheckForSourceRollOver())
   5099     {
   5100         if (iDataSource->GetAlternateSourceFormatType(iSourceFormatType,
   5101                 iAlternateSrcFormatIndex))
   5102         {
   5103             uint8 localbuffer[8];
   5104             oscl_memset(localbuffer, 0, 8);
   5105             localbuffer[0] = 1;
   5106             oscl_memcpy(&localbuffer[4], &iSourceFormatType, sizeof(uint32));
   5107 
   5108             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   5109             PVMFBasicErrorInfoMessage* infomsg =
   5110                 OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoAttemptingSourceRollOver, puuid, NULL));
   5111             SendInformationalEvent(PVMFInfoSourceFormatNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg), NULL, localbuffer, 8);
   5112             infomsg->removeRef();
   5113 
   5114             iAlternateSrcFormatIndex++;
   5115             PVMFStatus status = DoSetupSourceNode(aCmdId, aCmdContext);
   5116             if (status != PVMFSuccess)
   5117             {
   5118                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeRollOver() SourceNodeRollOver Failed, return status"));
   5119                 return status;
   5120             }
   5121             //roll over pending
   5122             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeRollOver() SourceNodeRollOver In Progress"));
   5123             return PVMFPending;
   5124         }
   5125     }
   5126     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeRollOver() Invalid State"));
   5127     return PVMFErrInvalidState;
   5128 }
   5129 
   5130 PVMFStatus PVPlayerEngine::DoAcquireLicense(PVPlayerEngineCommand& aCmd)
   5131 {
   5132     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   5133                     (0, "PVPlayerEngine::DoAcquireLicense() Tick=%d", OsclTickCount::TickCount()));
   5134 
   5135     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAcquireLicense() In"));
   5136 
   5137     // Retrieve the command parameters and validate
   5138     iCPMAcquireLicenseParam.iContentNameChar = NULL;
   5139     iCPMAcquireLicenseParam.iContentNameWChar = NULL;
   5140     iCPMAcquireLicenseParam.iTimeoutMsec = (-1);
   5141     iCPMAcquireLicenseParam.iLicenseData = NULL;
   5142     iCPMAcquireLicenseParam.iLicenseDataSize = 0;
   5143 
   5144     if (aCmd.GetParam(0).pOsclAny_value != NULL)
   5145     {
   5146         iCPMAcquireLicenseParam.iLicenseData = aCmd.GetParam(0).pOsclAny_value;
   5147     }
   5148 
   5149     if (aCmd.GetParam(1).uint32_value != 0)
   5150     {
   5151         iCPMAcquireLicenseParam.iLicenseDataSize = aCmd.GetParam(1).uint32_value;
   5152     }
   5153 
   5154     if (aCmd.GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR)
   5155     {
   5156         iCPMAcquireLicenseParam.iContentNameWChar = aCmd.GetParam(2).pWChar_value;
   5157     }
   5158     else
   5159     {
   5160         iCPMAcquireLicenseParam.iContentNameChar = aCmd.GetParam(2).pChar_value;
   5161     }
   5162     iCPMAcquireLicenseParam.iTimeoutMsec = aCmd.GetParam(3).int32_value;
   5163 
   5164     if (iCPMAcquireLicenseParam.iContentNameWChar == NULL && iCPMAcquireLicenseParam.iContentNameChar == NULL)
   5165     {
   5166         // Content name not specified
   5167         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Content name not specified."));
   5168         return PVMFErrArgument;
   5169     }
   5170 
   5171     if (iCPMAcquireLicenseParam.iTimeoutMsec < -1)
   5172     {
   5173         // Timeout parameter not valid
   5174         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Timeout value not valid."));
   5175         return PVMFErrArgument;
   5176     }
   5177 
   5178     // To acquire license, player data source and local data source need to be available
   5179     if (iDataSource == NULL)
   5180     {
   5181         // Player data source not available
   5182         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Player data source not specified."));
   5183         return PVMFErrNotReady;
   5184     }
   5185     if (iDataSource->GetDataSourceContextData() == NULL)
   5186     {
   5187         // Pointer to the local data source if not available
   5188         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Local data source in player data source not specified."));
   5189         return PVMFErrBadHandle;
   5190     }
   5191 
   5192     //If the license interface is available from the source node, use that.
   5193     if (iSourceNodeCPMLicenseIF != NULL)
   5194     {
   5195         PVMFStatus status = DoSourceNodeGetLicense(aCmd.GetCmdId(), aCmd.GetContext());
   5196         if (status != PVMFSuccess)
   5197             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() DoSourceNodeGetLicense failed."));
   5198 
   5199         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAcquireLicense() Out"));
   5200         return status;
   5201     }
   5202 
   5203     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAcquireLicense() Out"));
   5204     // if the license interface is not available from the source node, fail the command
   5205     return PVMFFailure;
   5206 }
   5207 
   5208 void PVPlayerEngine::DoCancelAcquireLicense(PVPlayerEngineCommand& aCmd)
   5209 {
   5210 
   5211     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   5212                     (0, "PVPlayerEngine::DoCancelAcquireLicense() Tick=%d", OsclTickCount::TickCount()));
   5213 
   5214     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAcquireLicense() In"));
   5215 
   5216     /* Engine cannot be processing another cancel command */
   5217     OSCL_ASSERT(iCmdToDlaCancel.empty() == true);
   5218 
   5219     PVMFCommandId id = aCmd.GetParam(0).int32_value;
   5220     PVMFStatus status = PVMFSuccess;
   5221 
   5222     if (iCurrentCmd.size() == 1)
   5223     {
   5224         /* First save the current command being processed */
   5225         PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
   5226 
   5227         /* First check "current" command if any */
   5228         if (id == iCurrentCmd[0].GetCmdId())
   5229         {
   5230             /* Cancel the current command first */
   5231             if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR
   5232                     || iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR)
   5233             {
   5234                 /* Make the CancelAll() command the current command */
   5235                 iCmdToDlaCancel.push_front(aCmd);
   5236                 /* Properly cancel a command being currently processed */
   5237                 if (iSourceNodeCPMLicenseIF != NULL)
   5238                 {
   5239                     /* Cancel the GetLicense */
   5240                     PVPlayerEngineContext* context = NULL;
   5241                     PVMFCommandId cmdid = -1;
   5242                     int32 leavecode = 0;
   5243                     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_SourceNodeCancelGetLicense);
   5244 
   5245                     OSCL_TRY(leavecode, cmdid = iSourceNodeCPMLicenseIF->CancelGetLicense(iSourceNodeSessionId, iCPMGetLicenseCmdId, (OsclAny*)context));
   5246                     if (leavecode)
   5247                     {
   5248                         FreeEngineContext(context);
   5249                         status = PVMFErrNotSupported;
   5250                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() CancelGetLicense on iSourceNode did a leave!"));
   5251                     }
   5252                 }
   5253                 else
   5254                 {
   5255                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() CPM plug-in registry in local data source not specified."));
   5256                     OSCL_ASSERT(false);
   5257                     status = PVMFErrBadHandle;
   5258                 }
   5259             }
   5260             else
   5261             {
   5262                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() Current cmd is not AquireLicense."));
   5263                 status = PVMFErrArgument;
   5264             }
   5265         }
   5266         else
   5267         {
   5268             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() Current cmd ID is not equal with App specified cmd ID."));
   5269             status = PVMFErrArgument;
   5270         }
   5271         if (status != PVMFSuccess)
   5272         {
   5273             /* We send error completetion for CancelAcquireLicense API*/
   5274             iCurrentCmd.erase(iCurrentCmd.begin());
   5275             iCurrentCmd.push_front(aCmd);
   5276             EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), status);
   5277             iCurrentCmd.push_front(currentcmd);
   5278         }
   5279     }
   5280     else
   5281     {
   5282         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() No Current cmd"));
   5283         iCurrentCmd.push_front(aCmd);
   5284         status = PVMFErrArgument;
   5285         /* If we get here the command isn't queued so the cancel fails */
   5286         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), status);
   5287     }
   5288 
   5289     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAcquireLicense() Out"));
   5290     return;
   5291 }
   5292 
   5293 PVMFStatus PVPlayerEngine::DoSourceNodeGetLicense(PVCommandId aCmdId, OsclAny* aCmdContext)
   5294 {
   5295     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   5296                     (0, "PVPlayerEngine::DoSourceNodeGetLicense() Tick=%d", OsclTickCount::TickCount()));
   5297 
   5298     OSCL_UNUSED_ARG(aCmdId);
   5299     OSCL_UNUSED_ARG(aCmdContext);
   5300 
   5301     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetLicense() In"));
   5302 
   5303     if (iSourceNodeCPMLicenseIF == NULL)
   5304     {
   5305         OSCL_ASSERT(false);
   5306         return PVMFErrBadHandle;
   5307     }
   5308 
   5309     // Get the license
   5310     PVPlayerEngineContext* context = NULL;
   5311     int32 leavecode = 0;
   5312     context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeGetLicense);
   5313     if (iCPMAcquireLicenseParam.iContentNameChar)
   5314     {
   5315         // Use the char version
   5316         iCPMContentNameStr = iCPMAcquireLicenseParam.iContentNameChar;
   5317         OSCL_TRY(leavecode, iCPMGetLicenseCmdId = iSourceNodeCPMLicenseIF->GetLicense(iSourceNodeSessionId,
   5318                  iCPMContentNameStr,
   5319                  iCPMAcquireLicenseParam.iLicenseData,
   5320                  iCPMAcquireLicenseParam.iLicenseDataSize,
   5321                  iCPMAcquireLicenseParam.iTimeoutMsec,
   5322                  (OsclAny*)context));
   5323     }
   5324     else if (iCPMAcquireLicenseParam.iContentNameWChar)
   5325     {
   5326         // Use the wchar version
   5327         iCPMContentNameWStr = iCPMAcquireLicenseParam.iContentNameWChar;
   5328         OSCL_TRY(leavecode, iCPMGetLicenseCmdId = iSourceNodeCPMLicenseIF->GetLicense(iSourceNodeSessionId,
   5329                  iCPMContentNameWStr,
   5330                  iCPMAcquireLicenseParam.iLicenseData,
   5331                  iCPMAcquireLicenseParam.iLicenseDataSize,
   5332                  iCPMAcquireLicenseParam.iTimeoutMsec,
   5333                  (OsclAny*)context));
   5334     }
   5335     else
   5336     {
   5337         // This should not happen
   5338         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeGetLicense() Content name not specified. Asserting"));
   5339         OSCL_ASSERT(false);
   5340         return PVMFErrArgument;
   5341     }
   5342 
   5343     if (leavecode)
   5344     {
   5345         FreeEngineContext(context);
   5346         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeGetLicense() GetLicense on iSourceNode did a leave!"));
   5347     }
   5348     else
   5349     {
   5350         ++iNumPendingNodeCmd;
   5351     }
   5352 
   5353     if (iNumPendingNodeCmd <= 0)
   5354     {
   5355         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetLicense() Out No pending QueryInterface() on source node"));
   5356         return PVMFFailure;
   5357     }
   5358 
   5359     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetLicense() Out"));
   5360     return PVMFSuccess;
   5361 }
   5362 
   5363 PVMFStatus PVPlayerEngine::DoAddDataSink(PVPlayerEngineCommand& aCmd)
   5364 {
   5365     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   5366                     (0, "PVPlayerEngine::DoAddDataSink() Tick=%d", OsclTickCount::TickCount()));
   5367 
   5368     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSink() In"));
   5369 
   5370     if (GetPVPlayerState() != PVP_STATE_INITIALIZED)
   5371     {
   5372         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSink() Wrong engine state"));
   5373         return PVMFErrInvalidState;
   5374     }
   5375 
   5376     if (aCmd.GetParam(0).pOsclAny_value == NULL)
   5377     {
   5378         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSink() Passed in parameter invalid."));
   5379         return PVMFErrArgument;
   5380     }
   5381 
   5382     PVPlayerDataSink* datasink = (PVPlayerDataSink*)(aCmd.GetParam(0).pOsclAny_value);
   5383 
   5384     PVPlayerEngineDatapath newdatapath;
   5385     newdatapath.iDataSink = datasink;
   5386 
   5387     // Add a new engine datapath to the list for the data sink
   5388     iDatapathList.push_back(newdatapath);
   5389 
   5390     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   5391 
   5392     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSink() Out"));
   5393     return PVMFSuccess;
   5394 }
   5395 
   5396 
   5397 PVMFStatus PVPlayerEngine::DoSetPlaybackRange(PVPlayerEngineCommand& aCmd)
   5398 {
   5399     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   5400                     (0, "PVPlayerEngine::DoSetPlaybackRange() Tick=%d", OsclTickCount::TickCount()));
   5401 
   5402     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRange() In"));
   5403 
   5404     PVMFStatus retval;
   5405 
   5406     if (GetPVPlayerState() == PVP_STATE_ERROR)
   5407     {
   5408         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRange() Wrong engine state"));
   5409         return PVMFErrInvalidState;
   5410     }
   5411 
   5412     if (aCmd.GetParam(2).bool_value)
   5413     {
   5414         // Queueing of playback range is not supported yet
   5415         iQueuedRangePresent = false;
   5416         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRange() Queued playback range is not supported yet"));
   5417         return PVMFErrNotSupported;
   5418     }
   5419 
   5420     // Change the end position
   5421     iCurrentEndPosition = aCmd.GetParam(1).playbackpos_value;
   5422     retval = UpdateCurrentEndPosition(iCurrentEndPosition);
   5423     if (retval != PVMFSuccess)
   5424     {
   5425         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRange() Changing end position failed"));
   5426         return retval;
   5427     }
   5428 
   5429     if (aCmd.GetParam(0).playbackpos_value.iIndeterminate)
   5430     {
   5431         // Start position not specified so return as success
   5432         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   5433         return PVMFSuccess;
   5434     }
   5435 
   5436     // reset repos related variables except the StreamID.
   5437     ResetReposVariables(false);
   5438     iStreamID++;
   5439 
   5440     // Reset the paused-due-to-EOS flag
   5441     iPlaybackPausedDueToEndOfClip = false;
   5442 
   5443     // Change the begin position
   5444     iCurrentBeginPosition = aCmd.GetParam(0).playbackpos_value;
   5445     iTargetNPT = iCurrentBeginPosition.iPosValue.millisec_value;
   5446     retval = UpdateCurrentBeginPosition(iCurrentBeginPosition, aCmd);
   5447 
   5448     if (retval == PVMFSuccess)
   5449     {
   5450         // Notify completion of engine command
   5451         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   5452     }
   5453     else if (retval == PVMFPending)
   5454     {
   5455         // SetPlaybackRange command is still being processed
   5456         // so change the return status so command is not completed yet
   5457         retval = PVMFSuccess;
   5458     }
   5459 
   5460     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRange() Out"));
   5461     return retval;
   5462 }
   5463 
   5464 
   5465 PVMFStatus PVPlayerEngine::UpdateCurrentEndPosition(PVPPlaybackPosition& aEndPos)
   5466 {
   5467     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentEndPosition() In"));
   5468 
   5469     if (aEndPos.iIndeterminate)
   5470     {
   5471         // Disable end time checking if running
   5472         if (iEndTimeCheckEnabled)
   5473         {
   5474             iEndTimeCheckEnabled = false;
   5475             iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   5476         }
   5477     }
   5478     else
   5479     {
   5480         // Convert the end time to milliseconds to have consistent units internally
   5481         uint32 timems = 0;
   5482         PVMFStatus retval = ConvertToMillisec(aEndPos, timems);
   5483         if (retval != PVMFSuccess)
   5484         {
   5485             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentEndPosition() Converting to millisec failed"));
   5486             return retval;
   5487         }
   5488         aEndPos.iPosValue.millisec_value = timems;
   5489         aEndPos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   5490 
   5491         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentEndPosition() Changing end time to %d ms", timems));
   5492 
   5493         // Enable the end time checking if not running
   5494         if (!iEndTimeCheckEnabled)
   5495         {
   5496             iEndTimeCheckEnabled = true;
   5497 
   5498             if (GetPVPlayerState() == PVP_STATE_STARTED)
   5499             {
   5500                 // Determine the check cycle based on interval setting in milliseconds
   5501                 // and timer frequency of 100 millisec
   5502                 int32 checkcycle = iEndTimeCheckInterval / 100;
   5503                 if (checkcycle == 0)
   5504                 {
   5505                     ++checkcycle;
   5506                 }
   5507                 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   5508                 iPollingCheckTimer->Request(PVPLAYERENGINE_TIMERID_ENDTIMECHECK, 0, checkcycle, this, true);
   5509             }
   5510         }
   5511     }
   5512 
   5513     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentEndPosition() Out"));
   5514     return PVMFSuccess;
   5515 }
   5516 
   5517 
   5518 PVMFStatus PVPlayerEngine::UpdateCurrentBeginPosition(PVPPlaybackPosition& aBeginPos, PVPlayerEngineCommand& aCmd)
   5519 {
   5520     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() In"));
   5521 
   5522     PVMFStatus retval = PVMFSuccess;
   5523     uint32 timems = 0;
   5524 
   5525     switch (GetPVPlayerState())
   5526     {
   5527         case PVP_STATE_PREPARED:
   5528         case PVP_STATE_STARTED:
   5529         {
   5530             // Change the playback position immediately
   5531             retval = ConvertToMillisec(aBeginPos, timems);
   5532             if (retval != PVMFSuccess)
   5533             {
   5534                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Converting to millisec failed"));
   5535                 return retval;
   5536             }
   5537 
   5538             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Requested begin position is %d ms", timems));
   5539 
   5540             retval = DoChangePlaybackPosition(aCmd.GetCmdId(), aCmd.GetContext());
   5541         }
   5542         break;
   5543 
   5544         case PVP_STATE_PAUSED:
   5545         {
   5546             // This is for use-case: Pause - SetPlaybackRate - Resume.
   5547             // In DoResume engine will call SetDataSourceDirection and then from HandleSourceNodeSetDataSourceDirection
   5548             // will call UpdateCurrentBeginPosition.
   5549             if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_RESUME)
   5550             {
   5551                 // Reposition occurred during the paused state so need to change the source position first
   5552                 retval = DoSourceNodeQueryDataSourcePosition(aCmd.GetCmdId(), aCmd.GetContext());
   5553                 if (retval == PVMFSuccess)
   5554                 {
   5555                     //return Pending to indicate a node command was issued
   5556                     return PVMFPending;
   5557                 }
   5558                 else
   5559                 {
   5560                     //ignore failure, continue with resume sequence
   5561                     return PVMFSuccess;
   5562                 }
   5563             }
   5564             else
   5565             {
   5566                 //if there's already a direction change pending, then don't
   5567                 //allow a reposition also
   5568                 if (iChangePlaybackDirectionWhenResuming)
   5569                 {
   5570                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Direction change already pending, fail."));
   5571                     return PVMFErrInvalidState;
   5572                 }
   5573 
   5574                 // Convert the time units but flag to change playback position when resuming
   5575                 retval = ConvertToMillisec(aBeginPos, timems);
   5576                 if (retval != PVMFSuccess)
   5577                 {
   5578                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Converting to millisec failed in paused state"));
   5579                     return retval;
   5580                 }
   5581 
   5582                 iChangePlaybackPositionWhenResuming = true;
   5583 
   5584                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Saving requested begin position(%d ms) for resume", timems));
   5585             }
   5586         }
   5587         break;
   5588 
   5589         default:
   5590             // Playback is stopped and start position is set so wait for playback to start
   5591             break;
   5592     }
   5593 
   5594     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Out"));
   5595     return retval;
   5596 }
   5597 
   5598 PVMFStatus PVPlayerEngine::DoChangePlaybackPosition(PVCommandId aCmdId, OsclAny* aCmdContext)
   5599 {
   5600     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoChangePlaybackPosition() In"));
   5601 
   5602     // Check if the source node has position control IF or
   5603     // begin position is indeterminate
   5604     if (iSourceNodePBCtrlIF == NULL ||
   5605             iCurrentBeginPosition.iIndeterminate ||
   5606             ((iCurrentBeginPosition.iPosUnit != PVPPBPOSUNIT_MILLISEC) &&
   5607              (iCurrentBeginPosition.iPlayListPosUnit != PVPPBPOSUNIT_MILLISEC)))
   5608     {
   5609         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoChangePlaybackPosition() Playback control IF on source node not available or invalid begin position"));
   5610         return PVMFFailure;
   5611     }
   5612 
   5613     PVMFCommandId cmdid = -1;
   5614 
   5615     if (iSeekToSyncPoint && iSyncPointSeekWindow > 0)
   5616     {
   5617         PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryDataSourcePositionDuringPlayback);
   5618 
   5619         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoChangePlaybackPosition() Querying source position. Position %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
   5620         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoChangePlaybackPosition() Querying source position. Position %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
   5621         int32 leavecode = 0;
   5622 
   5623         // As in case of MP4 file we need to call overload function of QueryDataSourcePosition which retruns
   5624         // I frame before and after instead of actaul NPT, format type will be checked here to first find if
   5625         // format-type is one of the MP4 varient
   5626 
   5627         PVMFNodeCapability nodeCapability;
   5628         iSourceNode->GetCapability(nodeCapability);
   5629         PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
   5630         bool mpeg4FormatType = false;
   5631         if (formatType != NULL)
   5632         {
   5633             if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
   5634             {
   5635                 mpeg4FormatType = true;
   5636             }
   5637             else
   5638             {
   5639                 mpeg4FormatType = false;
   5640             }
   5641         }
   5642 
   5643         if (mpeg4FormatType)
   5644         {
   5645             OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT,
   5646                                         iSeekPointBeforeTargetNPT, iSeekPointAfterTargetNPT, (OsclAny*)context, iSeekToSyncPoint));
   5647         }
   5648         else
   5649         {
   5650             OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT, iActualNPT,
   5651                                         iSeekToSyncPoint, (OsclAny*)context));
   5652         }
   5653 
   5654         OSCL_FIRST_CATCH_ANY(leavecode,
   5655                              FreeEngineContext(context);
   5656                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoChangePlaybackPosition() QueryDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
   5657                              if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   5658     {
   5659         return leavecode;
   5660     }
   5661     else
   5662     {
   5663         return PVMFFailure;
   5664     }
   5665                         );
   5666     }
   5667     else
   5668     {
   5669         // Go straight to repositioning the data source
   5670         PVMFStatus retval = DoSourceNodeSetDataSourcePositionDuringPlayback(aCmdId, aCmdContext);
   5671         if (retval == PVMFSuccess)
   5672         {
   5673             return PVMFPending;
   5674         }
   5675         else
   5676         {
   5677             return retval;
   5678         }
   5679     }
   5680 
   5681     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoChangePlaybackPosition() Out"));
   5682 
   5683     return PVMFPending;
   5684 }
   5685 
   5686 PVMFStatus PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback(PVCommandId aCmdId, OsclAny* aCmdContext)
   5687 {
   5688     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() In"));
   5689 
   5690     // Check if the source node has position control IF
   5691     if (iSourceNodePBCtrlIF == NULL)
   5692     {
   5693         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() No source playback control IF"));
   5694         return PVMFFailure;
   5695     }
   5696     bool clockpausedhere = false;
   5697     switch (iPlaybackPositionMode)
   5698     {
   5699         case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT:
   5700         case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION:
   5701             break;
   5702         case PVPPBPOS_MODE_NOW:
   5703         default:
   5704             // Pause the playback clock
   5705             clockpausedhere = iPlaybackClock.Pause();
   5706 
   5707             // Stop the playback position status timer
   5708             StopPlaybackStatusTimer();
   5709             break;
   5710     }
   5711     // Set the new position on the source node
   5712     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourcePositionDuringPlayback);
   5713 
   5714     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() Calling SetDataSourcePosition() on source node. TargetNPT %d ms, SeekToSyncPoint %d", iTargetNPT, iSeekToSyncPoint));
   5715 
   5716     int32 leavecode = 0;
   5717     if (iCurrentBeginPosition.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
   5718     {
   5719         iDataSourcePosParams.iActualMediaDataTS = 0;
   5720         iDataSourcePosParams.iActualNPT = 0;
   5721         if ((iCurrentBeginPosition.iMode == PVPPBPOS_MODE_UNKNOWN) ||
   5722                 (iCurrentBeginPosition.iMode == PVPPBPOS_MODE_NOW))
   5723         {
   5724             iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_MODE_NOW;
   5725         }
   5726         else if (iCurrentBeginPosition.iMode == PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT)
   5727         {
   5728             iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_END_OF_CURRENT_PLAY_ELEMENT;
   5729         }
   5730         else if (iCurrentBeginPosition.iMode == PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION)
   5731         {
   5732             iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_MODE_END_OF_CURRENT_PLAY_SESSION;
   5733         }
   5734         iDataSourcePosParams.iPlayElementIndex = iCurrentBeginPosition.iPlayElementIndex;
   5735         iDataSourcePosParams.iSeekToSyncPoint = iSeekToSyncPoint;
   5736         iDataSourcePosParams.iTargetNPT = iCurrentBeginPosition.iPlayListPosValue.millisec_value;
   5737         iDataSourcePosParams.iStreamID = iStreamID;
   5738         iDataSourcePosParams.iPlaylistUri = iCurrentBeginPosition.iPlayListUri;
   5739 
   5740         leavecode = IssueSourceSetDataSourcePosition(true, (OsclAny*)context);
   5741         if (leavecode != 0)
   5742         {
   5743             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
   5744             FreeEngineContext(context);
   5745             if (clockpausedhere)
   5746             {
   5747                 // Resume the clock if paused in this function
   5748                 StartPlaybackClock();
   5749             }
   5750 
   5751             --iStreamID;
   5752 
   5753             if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   5754             {
   5755                 return leavecode;
   5756             }
   5757             else
   5758             {
   5759                 return PVMFFailure;
   5760             }
   5761         }
   5762     }
   5763     else
   5764     {
   5765         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition on iSourceNodePBCtrlIF - TargetNPT=%d, SeekToSyncPoint=%d", iTargetNPT, iSeekToSyncPoint));
   5766         leavecode = IssueSourceSetDataSourcePosition(false, (OsclAny*)context);
   5767 
   5768         if (leavecode != 0)
   5769         {
   5770             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
   5771             FreeEngineContext(context);
   5772             if (clockpausedhere)
   5773             {
   5774                 // Resume the clock if paused in this function
   5775                 StartPlaybackClock();
   5776             }
   5777             --iStreamID;
   5778             if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   5779             {
   5780                 return leavecode;
   5781             }
   5782             else
   5783             {
   5784                 return PVMFFailure;
   5785             }
   5786         }
   5787     }
   5788     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() Out"));
   5789 
   5790     return PVMFSuccess;
   5791 }
   5792 
   5793 PVMFStatus PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback(PVCommandId aCmdId,
   5794         OsclAny* aCmdContext,
   5795         bool aSFR)
   5796 {
   5797     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   5798                     (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Tick=%d", OsclTickCount::TickCount()));
   5799 
   5800     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() In"));
   5801 
   5802     // Pause the playback clock
   5803     bool clockpausedhere = iPlaybackClock.Pause();
   5804 
   5805     // Tell the sink nodes to skip the unneeded media data
   5806     iNumPendingNodeCmd = 0;
   5807     int32 leavecode = 0;
   5808 
   5809     // For all sink node with sync control IF, call SkipMediaData()
   5810     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   5811     {
   5812         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   5813                         (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Calling SkipMediaData() on sink nodes. MediadataTS to flush to %d ms, MediadataTS to skip to %d ms", iActualMediaDataTS, iSkipMediaDataTS));
   5814 
   5815         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   5816                         (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Calling SkipMediaData() on sink nodes. MediadataTS to flush to %d ms, MediadataTS to skip to %d ms", iActualMediaDataTS, iSkipMediaDataTS));
   5817 
   5818         if (iDatapathList[i].iDatapath &&
   5819                 iDatapathList[i].iEndOfDataReceived == false &&
   5820                 iDatapathList[i].iSinkNodeSyncCtrlIF != NULL)
   5821         {
   5822             PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeSkipMediaDataDuringPlayback);
   5823             leavecode = IssueSinkSkipMediaData(&(iDatapathList[i]), aSFR, (OsclAny*) context);
   5824 
   5825             if (leavecode == 0)
   5826             {
   5827                 ++iNumPendingNodeCmd;
   5828                 ++iNumPendingSkipCompleteEvent;
   5829                 ++iNumPVMFInfoStartOfDataPending;
   5830             }
   5831             else
   5832             {
   5833                 FreeEngineContext(context);
   5834             }
   5835         }
   5836     }
   5837 
   5838     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Out"));
   5839     if (iNumPendingNodeCmd > 0)
   5840     {
   5841         return PVMFSuccess;
   5842     }
   5843     else
   5844     {
   5845         if (clockpausedhere)
   5846         {
   5847             // Resume the clock if paused in this function
   5848             StartPlaybackClock();
   5849         }
   5850 
   5851         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Skip on sink nodes failed"));
   5852         return PVMFFailure;
   5853     }
   5854 }
   5855 
   5856 
   5857 PVMFStatus PVPlayerEngine::DoGetPlaybackRange(PVPlayerEngineCommand& aCmd)
   5858 {
   5859     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRange() In"));
   5860 
   5861     if (aCmd.GetParam(0).pPlaybackpos_value == NULL ||
   5862             aCmd.GetParam(1).pPlaybackpos_value == NULL)
   5863     {
   5864         // User did not pass in the reference to write the start and stop positions
   5865         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Passed in parameter invalid."));
   5866         return PVMFErrArgument;
   5867     }
   5868 
   5869     if (aCmd.GetParam(2).bool_value)
   5870     {
   5871         // Return the queued playback range
   5872         if (iQueuedRangePresent)
   5873         {
   5874             *(aCmd.GetParam(0).pPlaybackpos_value) = iQueuedBeginPosition;
   5875             *(aCmd.GetParam(1).pPlaybackpos_value) = iQueuedEndPosition;
   5876         }
   5877         else
   5878         {
   5879             // Queued range has not been set
   5880             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Queued range not set"));
   5881             return PVMFErrNotReady;
   5882         }
   5883     }
   5884     else
   5885     {
   5886         PVMFStatus retval = PVMFSuccess;
   5887 
   5888         // Return the current playback range
   5889         if (iCurrentBeginPosition.iIndeterminate)
   5890         {
   5891             // Since indeterminate, just directly copy
   5892             *(aCmd.GetParam(0).pPlaybackpos_value) = iCurrentBeginPosition;
   5893         }
   5894         else
   5895         {
   5896             retval = ConvertFromMillisec(iCurrentBeginPosition.iPosValue.millisec_value, *(aCmd.GetParam(0).pPlaybackpos_value));
   5897             if (retval != PVMFSuccess)
   5898             {
   5899                 // The conversion failed.
   5900                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Conversion from millisec failed (1)"));
   5901                 return retval;
   5902             }
   5903         }
   5904 
   5905         if (iCurrentEndPosition.iIndeterminate)
   5906         {
   5907             // Since indeterminate, just directly copy
   5908             *(aCmd.GetParam(1).pPlaybackpos_value) = iCurrentEndPosition;
   5909         }
   5910         else
   5911         {
   5912             retval = ConvertFromMillisec(iCurrentEndPosition.iPosValue.millisec_value, *(aCmd.GetParam(1).pPlaybackpos_value));
   5913             if (retval != PVMFSuccess)
   5914             {
   5915                 // The conversion failed.
   5916                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Conversion from millisec failed (2)"));
   5917                 return retval;
   5918             }
   5919         }
   5920     }
   5921 
   5922     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   5923     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRange() Out"));
   5924     return PVMFSuccess;
   5925 }
   5926 
   5927 
   5928 PVMFStatus PVPlayerEngine::DoGetCurrentPosition(PVPlayerEngineCommand& aCmd, bool aSyncCmd)
   5929 {
   5930     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetCurrentPosition() In"));
   5931 
   5932     PVPPlaybackPosition* pbpos = aCmd.GetParam(0).pPlaybackpos_value;
   5933 
   5934     if (GetPVPlayerState() == PVP_STATE_IDLE ||
   5935             GetPVPlayerState() == PVP_STATE_ERROR)
   5936     {
   5937         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetCurrentPosition() Wrong engine state"));
   5938         return PVMFErrInvalidState;
   5939     }
   5940 
   5941     if (pbpos == NULL)
   5942     {
   5943         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetCurrentPosition() Passed in parameter invalid."));
   5944         return PVMFErrArgument;
   5945     }
   5946 
   5947     // Query playback clock for current playback position
   5948     GetPlaybackClockPosition(*pbpos);
   5949 
   5950     if (pbpos->iIndeterminate)
   5951     {
   5952         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetCurrentPosition() Passed in parameter invalid."));
   5953         return PVMFErrArgument;
   5954     }
   5955 
   5956     if (!aSyncCmd)
   5957     {
   5958         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   5959     }
   5960 
   5961     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetCurrentPosition() Out"));
   5962     return PVMFSuccess;
   5963 }
   5964 
   5965 
   5966 PVMFStatus PVPlayerEngine::DoSetPlaybackRate(PVPlayerEngineCommand& aCmd)
   5967 {
   5968     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() In"));
   5969 
   5970     int32 rate = aCmd.GetParam(0).int32_value;
   5971     PVMFTimebase* timebase = (PVMFTimebase*)(aCmd.GetParam(1).pOsclAny_value);
   5972 
   5973     // Split the rate into the absolute value plus the direction 1 or -1.
   5974     int32 direction = 1;
   5975     if (rate < 0)
   5976     {
   5977         direction = (-1);
   5978         rate = (-rate);
   5979     }
   5980 
   5981     // Check if called in valid states.
   5982     if (GetPVPlayerState() != PVP_STATE_PREPARED
   5983             && GetPVPlayerState() != PVP_STATE_STARTED
   5984             && GetPVPlayerState() != PVP_STATE_PAUSED)
   5985     {
   5986         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Wrong engine state to change rate"));
   5987         return PVMFErrInvalidState;
   5988     }
   5989 
   5990     // Timebase can only be changed when prepared or paused.
   5991     if (timebase != iOutsideTimebase
   5992             && GetPVPlayerState() != PVP_STATE_PREPARED
   5993             && GetPVPlayerState() != PVP_STATE_PAUSED)
   5994     {
   5995         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Wrong engine state to change timebase"));
   5996         return PVMFErrInvalidState;
   5997     }
   5998 
   5999     // Don't allow a direction change while paused, if there's already
   6000     // a pending reposition.  Engine doesn't have logic to handle both repos and
   6001     // direction change during the Resume.
   6002     if (direction != iPlaybackDirection
   6003             && GetPVPlayerState() == PVP_STATE_PAUSED
   6004             && iChangePlaybackPositionWhenResuming)
   6005     {
   6006         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Repos already pending-- can't change direction."));
   6007         return PVMFErrInvalidState;
   6008     }
   6009 
   6010     // Switching from forward to backward really only makes sense when playing or paused,
   6011     // otherwise we'll be at the end of clip.  If we ever allow combined repositioning
   6012     // and direction change, this restriction could be removed.
   6013     if (direction != iPlaybackDirection
   6014             && direction < 0
   6015             && GetPVPlayerState() != PVP_STATE_STARTED
   6016             && GetPVPlayerState() != PVP_STATE_PAUSED)
   6017     {
   6018         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Wrong engine state to go backward"));
   6019         return PVMFErrInvalidState;
   6020     }
   6021 
   6022     // Validate the playback rate parameters.
   6023 
   6024     // Rate zero is only valid with an outside timebase.
   6025     if (rate == 0
   6026             && timebase == NULL)
   6027     {
   6028         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Invalid parameter-- rate 0 with no outside timbase."));
   6029         return PVMFErrArgument;
   6030     }
   6031 
   6032     // Rate must be within allowed range
   6033     if (rate > 0
   6034             && (rate < PVP_PBRATE_MIN || rate > PVP_PBRATE_MAX))
   6035     {
   6036         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Invalid parameter-- rate outside allowed range"));
   6037         return PVMFErrArgument;
   6038     }
   6039 
   6040     // With an outside timebase, we can't really support rates.  If -1x is input,
   6041     // it means backward direction, but otherwise, rate is ignored.
   6042     // So flag an error for any rate other than zero, 1x, or -1x.
   6043     if (timebase != NULL
   6044             && (rate != 0 && rate != 100000))
   6045     {
   6046         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Invalid rate with outside timebase"));
   6047         return PVMFErrInvalidState;
   6048     }
   6049 
   6050     // To do any rate change, the source node must have the playback control IF.
   6051     if (rate != iPlaybackClockRate
   6052             && iSourceNodePBCtrlIF == NULL)
   6053     {
   6054         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() iSourceNodePBCtrlIF is NULL"));
   6055         return PVMFFailure;
   6056     }
   6057 
   6058     // To do any direction change, the source node must have the direction control IF.
   6059     if (direction != iPlaybackDirection
   6060             && iSourceNodeDirCtrlIF == NULL)
   6061     {
   6062         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() iSourceNodeDirCtrlIF is NULL"));
   6063         return PVMFFailure;
   6064     }
   6065 
   6066     // Reset the paused-due-to-EOS flag if direction changes
   6067     if (direction != iPlaybackDirection)
   6068     {
   6069         iPlaybackPausedDueToEndOfClip = false;
   6070         //a direction change also involves an internal repositioning
   6071         //so reset repos related variables and increment iStreamID
   6072         ResetReposVariables(false);
   6073         iStreamID++;
   6074     }
   6075 
   6076     // Save the new values.  They won't be installed until they're verified
   6077     iOutsideTimebase_New = timebase;
   6078     iPlaybackDirection_New = direction;
   6079     iPlaybackClockRate_New = rate;
   6080 
   6081     // Start the sequence.
   6082 
   6083     if (iPlaybackClockRate_New != iPlaybackClockRate)
   6084     {
   6085         // This code starts a rate change.  Any direction and/or timebase change
   6086         // will happen once the rate change is complete.
   6087 
   6088         // Query the source node if the new playback rate is supported
   6089         PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_SourceNodeSetDataSourceRate);
   6090 
   6091         PVMFCommandId cmdid = -1;
   6092         int32 leavecode = 0;
   6093         OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->SetDataSourceRate(iSourceNodeSessionId, iPlaybackClockRate_New, iOutsideTimebase_New, (OsclAny*)context));
   6094         OSCL_FIRST_CATCH_ANY(leavecode,
   6095                              FreeEngineContext(context);
   6096                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() SetDataSourceRate on iSourceNodePBCtrlIF did a leave!"));
   6097                              return PVMFFailure);
   6098 
   6099         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() Out"));
   6100 
   6101         return PVMFSuccess;
   6102         // wait for the source node callback, then HandleSourceNodeSetDataSourceRate
   6103     }
   6104 
   6105     if (iPlaybackDirection_New != iPlaybackDirection)
   6106     {
   6107         // Do a direction change without a rate change.
   6108         PVMFStatus status = UpdateCurrentDirection(aCmd.GetCmdId(), aCmd.GetContext());
   6109         switch (status)
   6110         {
   6111             case PVMFPending:
   6112                 // If we get here, engine is Prepared or Started, and we're now
   6113                 // waiting on source node command completion followed
   6114                 // by a call to HandleSourceNodeSetDataSource.
   6115                 // Set the return status to Success, since the caller does not expect
   6116                 // PVMFPending.
   6117                 status = PVMFSuccess;
   6118                 break;
   6119             case PVMFSuccess:
   6120                 // If we get here, engine is Paused or Stopped.  The SetPlaybackRate
   6121                 // command is done for now, but we need to set the direction when the
   6122                 // engine is resumed or prepared.
   6123                 if (iOutsideTimebase_New != iOutsideTimebase)
   6124                 {
   6125                     UpdateTimebaseAndRate();
   6126                 }
   6127                 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   6128                 break;
   6129             default:
   6130                 //failure!
   6131                 break;
   6132         }
   6133         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() Out"));
   6134         return status;
   6135     }
   6136 
   6137     //If we get here it's either a timebase change, or no change at all, so
   6138     //the engine command is complete.
   6139     if (iOutsideTimebase_New != iOutsideTimebase)
   6140     {
   6141         UpdateTimebaseAndRate();
   6142     }
   6143 
   6144     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   6145 
   6146     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() Out"));
   6147     return PVMFSuccess;
   6148 }
   6149 
   6150 PVMFStatus PVPlayerEngine::UpdateCurrentDirection(PVMFCommandId aCmdId, OsclAny* aCmdContext)
   6151 {
   6152     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() In"));
   6153 
   6154     // Launch a direction change sequence.
   6155 
   6156     PVMFStatus status = PVMFFailure;
   6157 
   6158     // Check if the source node has direction control
   6159     if (!iSourceNodeDirCtrlIF)
   6160     {
   6161         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentDirection() Direction control IF on source node not available "));
   6162         status = PVMFFailure;
   6163         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Out"));
   6164         return status;
   6165     }
   6166 
   6167     switch (GetPVPlayerState())
   6168     {
   6169         case PVP_STATE_PREPARED:
   6170         case PVP_STATE_STARTED:
   6171 
   6172             // Change the playback direction immediately
   6173             status = DoSourceNodeSetDataSourceDirection(aCmdId, aCmdContext);
   6174             if (status == PVMFSuccess)
   6175             {
   6176                 //return Pending to indicate there is still a node command pending.
   6177                 status = PVMFPending;
   6178             }
   6179             else
   6180             {
   6181                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() DoSourceNodeSetDataSourceDirection failed."));
   6182             }
   6183             break;
   6184 
   6185         case PVP_STATE_PAUSED:
   6186             if (iChangePlaybackPositionWhenResuming)
   6187             {
   6188                 //if there's already a reposition pending, don't allow
   6189                 //a direction change also.
   6190                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Reposition already pending-- can't change direction."));
   6191                 status = PVMFFailure;
   6192             }
   6193             else
   6194             {
   6195                 //The command will complete now-- but the direction change
   6196                 //won't actually occur until the engine Resume command.
   6197                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Setting iChangePlaybackDirectionWhenResuming."));
   6198                 iChangePlaybackDirectionWhenResuming = true;
   6199                 status = PVMFSuccess;
   6200             }
   6201             break;
   6202 
   6203         default:
   6204             //not supported.
   6205             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Invalid engine state"));
   6206             status = PVMFErrInvalidState;
   6207             break;
   6208     }
   6209 
   6210     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Out"));
   6211     return status;
   6212 }
   6213 
   6214 PVMFStatus PVPlayerEngine::DoGetPlaybackRate(PVPlayerEngineCommand& aCmd)
   6215 {
   6216     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRate() In"));
   6217 
   6218     int32* rate = aCmd.GetParam(0).pInt32_value;
   6219     PVMFTimebase** timebase = (PVMFTimebase**)(aCmd.GetParam(1).pOsclAny_value);
   6220 
   6221     if (rate == NULL || timebase == NULL)
   6222     {
   6223         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRate() Passed in parameter invalid"));
   6224         return PVMFErrArgument;
   6225     }
   6226 
   6227     if (GetPVPlayerState() != PVP_STATE_PREPARED &&
   6228             GetPVPlayerState() != PVP_STATE_STARTED &&
   6229             GetPVPlayerState() != PVP_STATE_PAUSED)
   6230     {
   6231         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRate() Wrong engine state"));
   6232         return PVMFErrInvalidState;
   6233     }
   6234 
   6235     // Fill in with current engine settings for playback rate
   6236     *rate = iPlaybackClockRate * iPlaybackDirection;
   6237     *timebase = iOutsideTimebase;
   6238 
   6239     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   6240 
   6241     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRate() Out"));
   6242     return PVMFSuccess;
   6243 }
   6244 
   6245 
   6246 PVMFStatus PVPlayerEngine::DoGetPlaybackMinMaxRate(PVPlayerEngineCommand& aCmd)
   6247 {
   6248     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackMinMaxRate() In"));
   6249 
   6250     int32* minrate = aCmd.GetParam(0).pInt32_value;
   6251     int32* maxrate = aCmd.GetParam(1).pInt32_value;
   6252 
   6253     if (minrate == NULL || maxrate == NULL)
   6254     {
   6255         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackMinMaxRate() Passed in parameter invalid"));
   6256         return PVMFErrArgument;
   6257     }
   6258 
   6259     // Use hardcoded ranges for now
   6260     *minrate = PVP_PBRATE_MIN;
   6261     *maxrate = PVP_PBRATE_MAX;
   6262 
   6263     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   6264 
   6265     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackMinMaxRate() Out"));
   6266     return PVMFSuccess;
   6267 }
   6268 
   6269 
   6270 PVMFStatus PVPlayerEngine::DoPrepare(PVPlayerEngineCommand& aCmd)
   6271 {
   6272     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   6273                     (0, "PVPlayerEngine::DoPrepare() Tick=%d", OsclTickCount::TickCount()));
   6274 
   6275     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPrepare() In"));
   6276 
   6277     if (GetPVPlayerState() == PVP_STATE_PREPARED)
   6278     {
   6279         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Engine already in Prepared State"));
   6280         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   6281         return PVMFSuccess;
   6282     }
   6283 
   6284     if (GetPVPlayerState() != PVP_STATE_INITIALIZED)
   6285     {
   6286         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Wrong engine state"));
   6287         return PVMFErrInvalidState;
   6288     }
   6289 
   6290     if (iState == PVP_ENGINE_STATE_PREPARING)
   6291     {
   6292         // Engine is already in PREPARING STATE and doing Track selection. DoPrepare will be called everytime
   6293         // engine completes a stage of track selection and flips the state to _TRACK_SELECTION_1_DONE etc.
   6294         // If DoPrepare called without flipping the state, that means in _PREPARING state, do nothing here
   6295         // just return.
   6296         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   6297                         (0, "PVPlayerEngine::DoPrepare() Engine state PVP_ENGINE_STATE_PREPARING - Do Nothing"));
   6298         return PVMFSuccess;
   6299     }
   6300 
   6301     PVMFStatus cmdstatus = PVMFFailure;
   6302 
   6303     /* Engine will call DoPrepare 4 times
   6304      * 1) When Engine is in PVP_ENGINE_STATE_INITIALIZED state, here engine will start the Track Selection, which
   6305      * will start with Sink Nodes.
   6306      * 2) After Init completes on Sink nodes Engine will be in PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE and Engine will
   6307      * start creating Dec nodes and call Init on dec nodes, if needed.
   6308      * 3) Init completion on Dec nodes will take Engine to PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE and Engine will
   6309      * start populating the Playable List after verifying parameters of different tracks. Engine after selecting
   6310      * tracks will call Reset on Sink and Dec nodes.
   6311      * 4) Once Reset completes on Sink and Dec nodes, Engine will be in PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE and then
   6312      * Engine will delete all the unused dec nodes.
   6313      */
   6314     if (iState == PVP_ENGINE_STATE_INITIALIZED)
   6315     {
   6316         SetEngineState(PVP_ENGINE_STATE_PREPARING);
   6317 
   6318         // Reset the paused-due-to-EOS flag
   6319         iPlaybackPausedDueToEndOfClip = false;
   6320 
   6321         if (iDatapathList.empty() == true)
   6322         {
   6323             // No sink added so fail
   6324             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Data sinks not added."));
   6325             return PVMFErrNotReady;
   6326         }
   6327 
   6328         // Query cap-config based on available engine datapaths
   6329         cmdstatus = DoSinkNodeQueryCapConfigIF(aCmd.GetCmdId(), aCmd.GetContext());
   6330         if (cmdstatus != PVMFSuccess)
   6331         {
   6332             bool ehPending = CheckForPendingErrorHandlingCmd();
   6333             if (ehPending)
   6334             {
   6335                 // there should be no error handling queued.
   6336                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
   6337                 return PVMFPending;
   6338             }
   6339             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSinkNodeQueryCapConfigIF: failed, Add EH command"));
   6340             iCommandCompleteStatusInErrorHandling = cmdstatus;
   6341             iCommandCompleteErrMsgInErrorHandling = NULL;
   6342             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   6343             return PVMFPending;
   6344         }
   6345     }
   6346     else if (iState == PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE)
   6347     {
   6348         SetEngineState(PVP_ENGINE_STATE_PREPARING);
   6349 
   6350         // Now check for the tracks which can be played only using the Sink nodes, that means no Decoder node needed.
   6351         cmdstatus = DoSinkNodeTrackSelection(aCmd.GetCmdId(), aCmd.GetContext());
   6352         if (cmdstatus != PVMFSuccess)
   6353         {
   6354             bool ehPending = CheckForPendingErrorHandlingCmd();
   6355             if (ehPending)
   6356             {
   6357                 // there should be no error handling queued.
   6358                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
   6359                 return PVMFPending;
   6360             }
   6361             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSinkNodeTrackSelection: failed, Add EH command"));
   6362             iCommandCompleteStatusInErrorHandling = cmdstatus;
   6363             iCommandCompleteErrMsgInErrorHandling = NULL;
   6364             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   6365             return PVMFPending;
   6366         }
   6367 
   6368         // For the tracks which cannot be played by Sink nodes only, we need to instantiate decoder nodes.
   6369         // Create Decoder nodes and query for the cap and config IF here.
   6370         cmdstatus = DoDecNodeQueryCapConfigIF(aCmd.GetCmdId(), aCmd.GetContext());
   6371         if (cmdstatus != PVMFSuccess)
   6372         {
   6373             bool ehPending = CheckForPendingErrorHandlingCmd();
   6374             if (ehPending)
   6375             {
   6376                 // there should be no error handling queued.
   6377                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
   6378                 return PVMFPending;
   6379             }
   6380             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoDecNodeQueryCapConfigIF: failed, Add EH command"));
   6381             iCommandCompleteStatusInErrorHandling = cmdstatus;
   6382             iCommandCompleteErrMsgInErrorHandling = NULL;
   6383             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   6384             return PVMFPending;
   6385         }
   6386     }
   6387     else if (iState == PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE)
   6388     {
   6389         SetEngineState(PVP_ENGINE_STATE_PREPARING);
   6390 
   6391         cmdstatus = DoSourceNodeTrackSelection(aCmd.GetCmdId(), aCmd.GetContext());
   6392         if (cmdstatus != PVMFSuccess)
   6393         {
   6394             bool ehPending = CheckForPendingErrorHandlingCmd();
   6395             if (ehPending)
   6396             {
   6397                 // there should be no error handling queued.
   6398                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
   6399                 return PVMFPending;
   6400             }
   6401             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSourceNodeTrackSelection: failed, Add EH command"));
   6402             iCommandCompleteStatusInErrorHandling = cmdstatus;
   6403             iCommandCompleteErrMsgInErrorHandling = NULL;
   6404             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   6405             return PVMFPending;
   6406         }
   6407         // Reset all the sink and decoder nodes.
   6408         cmdstatus = DoSinkNodeDecNodeReset(aCmd.GetCmdId(), aCmd.GetContext());
   6409         if (cmdstatus != PVMFSuccess)
   6410         {
   6411             bool ehPending = CheckForPendingErrorHandlingCmd();
   6412             if (ehPending)
   6413             {
   6414                 // there should be no error handling queued.
   6415                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
   6416                 return PVMFPending;
   6417             }
   6418             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSinkNodeDecNodeReset: failed, Add EH command"));
   6419             iCommandCompleteStatusInErrorHandling = cmdstatus;
   6420             iCommandCompleteErrMsgInErrorHandling = NULL;
   6421             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   6422             return PVMFPending;
   6423         }
   6424     }
   6425     else if (iState == PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE)
   6426     {
   6427         SetEngineState(PVP_ENGINE_STATE_PREPARING);
   6428 
   6429         cmdstatus = DoSinkDecCleanupSourcePrepare(aCmd.GetCmdId(), aCmd.GetContext());
   6430         if (cmdstatus != PVMFSuccess)
   6431         {
   6432             bool ehPending = CheckForPendingErrorHandlingCmd();
   6433             if (ehPending)
   6434             {
   6435                 // there should be no error handling queued.
   6436                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
   6437                 return PVMFPending;
   6438             }
   6439             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoDecNodeCleanup: failed, Add EH command"));
   6440             iCommandCompleteStatusInErrorHandling = cmdstatus;
   6441             iCommandCompleteErrMsgInErrorHandling = NULL;
   6442             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   6443             return PVMFPending;
   6444         }
   6445     }
   6446 
   6447     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPrepare() Out"));
   6448     return PVMFSuccess;
   6449 }
   6450 
   6451 PVMFStatus PVPlayerEngine::DoSinkNodeQueryCapConfigIF(PVCommandId aCmdId, OsclAny* aCmdContext)
   6452 {
   6453     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() In"));
   6454 
   6455     if (iSourceNodeTrackSelIF == NULL)
   6456     {
   6457         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Source node track sel IF not available. Asserting"));
   6458         return PVMFFailure;
   6459     }
   6460 
   6461     uint32 i = 0;
   6462     int32 leavecode = 0;
   6463     uint32 numTracks = 0;
   6464     PVPlayerEngineContext* context = NULL;
   6465     PVMFCommandId cmdid = -1;
   6466     iNumPendingNodeCmd = 0;
   6467 
   6468     if (iSourceNodeTrackSelIF->GetMediaPresentationInfo(iSourcePresInfoList) != PVMFSuccess)
   6469     {
   6470         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() GetMediaPresentationInfo() call on source node failed"));
   6471         return PVMFFailure;
   6472     }
   6473 
   6474     numTracks = iSourcePresInfoList.getNumTracks();
   6475     iTrackSelectionList.reserve(numTracks);
   6476 
   6477     for (i = 0; i < numTracks; i++)
   6478     {
   6479         // Create the track selection list, which will store a set of sink and dec node (if needed) for each track.
   6480         PVPlayerEngineTrackSelection trackSelection;
   6481 
   6482         PVMFTrackInfo* trackInfo = iSourcePresInfoList.getTrackInfo(i);
   6483         trackSelection.iTsTrackID = trackInfo->getTrackID();
   6484 
   6485         iTrackSelectionList.push_back(trackSelection);
   6486     }
   6487 
   6488     for (i = 0; i < iDatapathList.size(); ++i)
   6489     {
   6490         // Destroy the track info if present
   6491         if (iDatapathList[i].iTrackInfo)
   6492         {
   6493             OSCL_DELETE(iDatapathList[i].iTrackInfo);
   6494             iDatapathList[i].iTrackInfo = NULL;
   6495         }
   6496 
   6497         if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
   6498         {
   6499             // Create file output node for sink
   6500             leavecode = 0;
   6501             OSCL_TRY(leavecode, iDatapathList[i].iSinkNode = PVFileOutputNodeFactory::CreateFileOutput());
   6502             OSCL_FIRST_CATCH_ANY(leavecode,
   6503                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Creation of file output node did a leave!"));
   6504                                  return PVMFErrNoMemory);
   6505         }
   6506         else if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_SINKNODE)
   6507         {
   6508             // Use the specified output node for sink node
   6509             iDatapathList[i].iSinkNode = iDatapathList[i].iDataSink->GetDataSinkNodeInterface();
   6510             if (iDatapathList[i].iSinkNode == NULL)
   6511             {
   6512                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Passed in sink node is NULL"));
   6513                 return PVMFFailure;
   6514             }
   6515         }
   6516         else
   6517         {
   6518             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Unsupported player data sink type"));
   6519             return PVMFErrNotSupported;
   6520         }
   6521 
   6522         if (iDatapathList[i].iSinkNode->ThreadLogon() != PVMFSuccess)
   6523         {
   6524             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() ThreadLogon() on passed-in sink node failed"));
   6525             OSCL_ASSERT(false);
   6526             return PVMFFailure;
   6527         }
   6528 
   6529         PVMFNodeSessionInfo nodesessioninfo(this, this, (OsclAny*)iDatapathList[i].iSinkNode, this, (OsclAny*)iDatapathList[i].iSinkNode);
   6530         iDatapathList[i].iSinkNodeSessionId = iDatapathList[i].iSinkNode->Connect(nodesessioninfo);
   6531 
   6532         // Query for Cap-Config IF
   6533         context = AllocateEngineContext(&iDatapathList[i], iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeQueryCapConfigIF);
   6534 
   6535         PVUuid capconfiguuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID;
   6536         cmdid = -1;
   6537         leavecode = 0;
   6538         iDatapathList[i].iSinkNodePVInterfaceCapConfig = NULL;
   6539         leavecode = IssueQueryInterface(iDatapathList[i].iSinkNode, iDatapathList[i].iSinkNodeSessionId, capconfiguuid, iDatapathList[i].iSinkNodePVInterfaceCapConfig, (OsclAny*)context, cmdid);
   6540         if (leavecode != 0 || cmdid == -1)
   6541         {
   6542             iDatapathList[i].iSinkNodePVInterfaceCapConfig = NULL;
   6543             FreeEngineContext(context);
   6544             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() QueryInterface on sink node for cap-config IF did a leave!"));
   6545             return PVMFFailure;
   6546         }
   6547         else
   6548         {
   6549             ++iNumPendingNodeCmd;
   6550         }
   6551     }
   6552 
   6553     if (iNumPendingNodeCmd <= 0)
   6554     {
   6555         // NumPendingNodeCmd less than or equal to zero means that none of the Sink nodes support Cap-Config interface, which means that these
   6556         // sinks cannot be used for playing the content. Return PVMFErrNotSupported from here which will take engine into Error handling and will fail
   6557         // Prepare command.
   6558         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Out No pending QueryInterface() on sink node"));
   6559         return PVMFErrNotSupported;
   6560     }
   6561 
   6562     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Out"));
   6563     return PVMFSuccess;
   6564 }
   6565 
   6566 PVMFStatus PVPlayerEngine::DoSinkNodeInit(PVCommandId aCmdId, OsclAny* aCmdContext)
   6567 {
   6568     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   6569                     (0, "PVPlayerEngine::DoSinkNodeInit() Tick=%d", OsclTickCount::TickCount()));
   6570 
   6571     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeInit() In"));
   6572 
   6573     iNumPendingNodeCmd = 0;
   6574     PVMFCommandId cmdid = -1;
   6575     int32 leavecode = 0;
   6576 
   6577     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   6578     {
   6579         if (iDatapathList[i].iSinkNode != NULL)
   6580         {
   6581             // Call Init() on the sink node
   6582             PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeInit);
   6583 
   6584             leavecode = IssueSinkNodeInit(&(iDatapathList[i]), (OsclAny*) context, cmdid);
   6585 
   6586             if (cmdid != -1 && leavecode == 0)
   6587             {
   6588                 ++iNumPendingNodeCmd;
   6589             }
   6590             else
   6591             {
   6592                 FreeEngineContext(context);
   6593                 return PVMFFailure;
   6594             }
   6595         }
   6596     }
   6597 
   6598     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeInit() Out"));
   6599     return PVMFSuccess;
   6600 }
   6601 
   6602 PVMFStatus PVPlayerEngine::DoSinkNodeTrackSelection(PVCommandId aCmdId, OsclAny* aCmdContext)
   6603 {
   6604     OSCL_UNUSED_ARG(aCmdId);
   6605     OSCL_UNUSED_ARG(aCmdContext);
   6606     // For a track to be playable only by sink node, the Sink node should support the Format Type and Format Specific Info
   6607     // for the track. If any of the 2 variables are not supported by the sink node, the track needs to have a decoder which
   6608     // will be created in next stage of track selection. If Sink node supports both the above variables for a particular
   6609     // track, the track will make to the Playable list without any decoder node.
   6610     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeTrackSelection() In"));
   6611 
   6612     PVMFStatus status = PVMFFailure;
   6613 
   6614     PvmiKvp kvpFormatType;
   6615     PvmiKvp kvpFSI;
   6616 
   6617     OSCL_StackString<64> iKVPFormatType = _STRLIT_CHAR(PVMF_FORMAT_TYPE_VALUE_KEY);
   6618 
   6619     const char* aFormatValType = PVMF_FORMAT_SPECIFIC_INFO_KEY;
   6620 
   6621     OsclMemAllocator alloc;
   6622 
   6623     kvpFormatType.key = NULL;
   6624     kvpFSI.key = NULL;
   6625 
   6626     kvpFormatType.key = iKVPFormatType.get_str();
   6627 
   6628     kvpFSI.length = oscl_strlen(aFormatValType) + 1; // +1 for \0
   6629     kvpFSI.key = (PvmiKeyType)alloc.ALLOCATE(kvpFSI.length);
   6630     if (kvpFSI.key == NULL)
   6631     {
   6632         return PVMFErrNoMemory;
   6633     }
   6634     oscl_strncpy(kvpFSI.key, aFormatValType, kvpFSI.length);
   6635 
   6636     for (uint32 i = 0; i < iDatapathList.size(); i++)
   6637     {
   6638         if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
   6639         {
   6640             for (uint32 j = 0; j < iSourcePresInfoList.getNumTracks(); j++)
   6641             {
   6642                 // if any track is already been added to the playlist then no need to check with the next Datapath
   6643                 // go onto the next track
   6644                 if (!iTrackSelectionList[j].iTsTrackValidForPlayableList)
   6645                 {
   6646                     OsclRefCounterMemFrag aConfig;
   6647                     PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(j);
   6648                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeTrackSelection() Check format type for %s", currTrack->getTrackMimeType().get_cstr()));
   6649 
   6650                     kvpFormatType.value.pChar_value = currTrack->getTrackMimeType().get_str();
   6651 
   6652                     // Check for the format type of the track first. If Supported move to Format specific info, if not
   6653                     // move on to the next track.
   6654 
   6655                     status = iDatapathList[i].iSinkNodeCapConfigIF->verifyParametersSync(NULL, &kvpFormatType, 1);
   6656 
   6657                     if (status == PVMFSuccess)
   6658                     {
   6659                         // go ahead and check for Format specific info
   6660                         aConfig = currTrack->getTrackConfigInfo();
   6661                         kvpFSI.value.key_specific_value = (OsclAny*)(aConfig.getMemFragPtr());
   6662                         kvpFSI.capacity = aConfig.getMemFragSize();
   6663 
   6664                         status = iDatapathList[i].iSinkNodeCapConfigIF->verifyParametersSync(NULL, &kvpFSI, 1);
   6665 
   6666                         if (status == PVMFSuccess)
   6667                         {
   6668                             // This track can be played just using the Sink nodes we need not have decoders for this track
   6669                             // Set the boolean iTsTrackValidForPlayableList to true in the TrackSelectionList.
   6670                             // Check the boolean iTsTrackValidForPlayableList before creating the decoder nodes, if
   6671                             // already set no need for decoders.
   6672                             iTrackSelectionList[j].iTsSinkNode = iDatapathList[i].iSinkNode;
   6673                             iTrackSelectionList[j].iTsSinkNodeCapConfigIF = iDatapathList[i].iSinkNodeCapConfigIF;
   6674                             iTrackSelectionList[j].iTsTrackValidForPlayableList = true;
   6675                         }
   6676                     }
   6677                 }
   6678                 // if any of the above verifyParameterSync returns a failure, just move onto the next track.
   6679             }
   6680         }
   6681     }
   6682 
   6683     alloc.deallocate((OsclAny*)(kvpFSI.key));
   6684     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeTrackSelection() Out"));
   6685     return PVMFSuccess;
   6686 }
   6687 
   6688 PVMFStatus PVPlayerEngine::DoDecNodeQueryCapConfigIF(PVCommandId aCmdId, OsclAny* aCmdContext)
   6689 {
   6690     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() In"));
   6691 
   6692     int32 leavecode = 0;
   6693     PVPlayerEngineContext* context = NULL;
   6694     PVMFCommandId cmdid = -1;
   6695 
   6696     PVMFFormatType iSrcFormat = 0;
   6697     PVMFFormatType iSinkFormat = 0;
   6698 
   6699     iNumPendingNodeCmd = 0;
   6700 
   6701     uint32 numTracks = iSourcePresInfoList.getNumTracks();
   6702 
   6703     for (uint32 i = 0; i < numTracks; i++)
   6704     {
   6705         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Check the track"));
   6706         for (uint32 j = 0; j < iDatapathList.size(); j++)
   6707         {
   6708             // Start creating decoder nodes for tracks which cannot be played with Sink nodes alone.
   6709             // It is also possible that there can be similar tracks with same mime strings but with
   6710             // different config parameters which share the same decoder node. For these similar tracks
   6711             // engine should not create decoder nodes again, it should use the same decoder node instance.
   6712             if (iTrackSelectionList[i].iTsDecNode == NULL && !iTrackSelectionList[i].iTsTrackValidForPlayableList)
   6713             {
   6714                 PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
   6715                 iSrcFormat = currTrack->getTrackMimeType().get_str();
   6716 
   6717                 //Try to get supported formats from the media I/O component.
   6718                 PvmiKvp* kvp = NULL;
   6719                 int numParams = 0;
   6720                 PVMFStatus status = iDatapathList[j].iSinkNodeCapConfigIF->getParametersSync(NULL, (char*)INPUT_FORMATS_CAP_QUERY, kvp, numParams, NULL);
   6721                 if (status == PVMFSuccess)
   6722                 {
   6723                     for (int k = 0; k < numParams; k++)
   6724                     {
   6725                         iSinkFormat = kvp[k].value.pChar_value;
   6726 
   6727                         Oscl_Vector<PVUuid, OsclMemAllocator> foundUuids;
   6728                         // Query the player node registry for the required decoder node
   6729                         if (iPlayerNodeRegistry.QueryRegistry(iSrcFormat, iSinkFormat, foundUuids) == PVMFSuccess)
   6730                         {
   6731                             if (!foundUuids.empty())
   6732                             {
   6733                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Node found for %s, sink %s", currTrack->getTrackMimeType().get_str(), iSinkFormat.getMIMEStrPtr()));
   6734                                 iTrackSelectionList[i].iTsDecNode = iPlayerNodeRegistry.CreateNode(foundUuids[0], iHwAccelerated);
   6735 
   6736                                 if (iTrackSelectionList[i].iTsDecNode != NULL)
   6737                                 {
   6738                                     iNodeUuids.push_back(PVPlayerEngineUuidNodeMapping(foundUuids[0], iTrackSelectionList[i].iTsDecNode));
   6739 
   6740                                     if (iTrackSelectionList[i].iTsDecNode->ThreadLogon() != PVMFSuccess)
   6741                                     {
   6742                                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() ThreadLogon() on dec node failed"));
   6743                                         OSCL_ASSERT(false);
   6744                                     }
   6745 
   6746                                     PVMFNodeSessionInfo nodesessioninfo(this, this, (OsclAny*)iTrackSelectionList[i].iTsDecNode, this, (OsclAny*)iTrackSelectionList[i].iTsDecNode);
   6747                                     iTrackSelectionList[i].iTsDecNodeSessionId = iTrackSelectionList[i].iTsDecNode->Connect(nodesessioninfo);
   6748 
   6749                                     // Query for CapConfig IF
   6750                                     context = AllocateEngineContext(NULL, iTrackSelectionList[i].iTsDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_DecNodeQueryCapConfigIF);
   6751 
   6752                                     PVUuid capconfiguuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID;
   6753                                     cmdid = -1;
   6754                                     iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
   6755                                     leavecode = IssueQueryInterface(iTrackSelectionList[i].iTsDecNode, iTrackSelectionList[i].iTsDecNodeSessionId, capconfiguuid, iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig, (OsclAny*)context, cmdid);
   6756                                     if (cmdid == -1 || leavecode != 0)
   6757                                     {
   6758                                         iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
   6759                                         FreeEngineContext(context);
   6760                                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() QueryInterface on dec node for cap-config IF did a leave!"));
   6761                                     }
   6762                                     else
   6763                                     {
   6764                                         ++iNumPendingNodeCmd;
   6765                                     }
   6766 
   6767                                     // A decoder is found in the registry and succesfully created for the particular set of track and datapath.
   6768                                     // Set the sink nodes and its cap and config IF for the track in trackSelectionList
   6769                                     iTrackSelectionList[i].iTsSinkNode = iDatapathList[j].iSinkNode;
   6770                                     iTrackSelectionList[i].iTsSinkNodeCapConfigIF = iDatapathList[j].iSinkNodeCapConfigIF;
   6771                                     iTrackSelectionList[i].iTsSinkNodeSessionId = iDatapathList[j].iSinkNodeSessionId;
   6772 
   6773                                     // Set the sink format for the datapath.
   6774                                     iDatapathList[j].iSinkFormat = iSinkFormat;
   6775 
   6776                                     // Valid decoder node set in TrackSelectionList. Scan the TrackSelectionList further and if
   6777                                     // any similar MIME track is there just use the same decoder and the same sink nodes.
   6778                                     for (uint32 s = i + 1; s < numTracks; s++)
   6779                                     {
   6780                                         PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(s);
   6781                                         if (!(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())))
   6782                                         {
   6783                                             iTrackSelectionList[s].iTsSinkNode = iTrackSelectionList[i].iTsSinkNode;
   6784                                             iTrackSelectionList[s].iTsSinkNodeCapConfigIF = iTrackSelectionList[i].iTsSinkNodeCapConfigIF;
   6785                                             iTrackSelectionList[s].iTsSinkNodeSessionId = iTrackSelectionList[i].iTsSinkNodeSessionId;
   6786 
   6787                                             iTrackSelectionList[s].iTsDecNode = iTrackSelectionList[i].iTsDecNode;
   6788                                             iTrackSelectionList[s].iTsDecNodeSessionId = iTrackSelectionList[i].iTsDecNodeSessionId;
   6789                                         }
   6790                                     }
   6791 
   6792                                     k = numParams;
   6793                                 }
   6794                                 else
   6795                                 {
   6796                                     // Create node on decoder failed, check with the next sink format
   6797                                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Dec node creation failed"));
   6798                                 }
   6799                             }
   6800                             else
   6801                             {
   6802                                 // No matching node found with the given Sinkformat, check with the next Sink Format
   6803                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() No matching decoder node found"));
   6804                             }
   6805                         }
   6806                         else
   6807                         {
   6808                             // Registry query failed with the given Sinkformat, check with the next Sink Format.
   6809                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Registry query for dec node failed"));
   6810                         }
   6811                     }
   6812                     iDatapathList[j].iSinkNodeCapConfigIF->releaseParameters(0, kvp, numParams);
   6813                 }
   6814                 else
   6815                 {
   6816                     // getParamterSync on MIO node to get the supported formats by MIO failed
   6817                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() getParamterSync on MIO node to get the supported formats by MIO failed"));
   6818                 }
   6819             }
   6820         }
   6821     }
   6822 
   6823     if (iNumPendingNodeCmd == 0)
   6824     {
   6825         // no decoder nodes are needed, go ahead for track selection logic
   6826         SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE);
   6827         RunIfNotReady();
   6828     }
   6829     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Out"));
   6830     return PVMFSuccess;
   6831 }
   6832 
   6833 PVMFStatus PVPlayerEngine::DoDecNodeInit(PVCommandId aCmdId, OsclAny* aCmdContext)
   6834 {
   6835     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   6836                     (0, "PVPlayerEngine::DoDecNodeInit() Tick=%d", OsclTickCount::TickCount()));
   6837 
   6838     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeInit() In"));
   6839 
   6840     iNumPendingNodeCmd = 0;
   6841     PVMFCommandId cmdid = -1;
   6842     int32 leavecode = 0;
   6843 
   6844     for (uint32 i = 0; i < iTrackSelectionList.size(); ++i)
   6845     {
   6846         if (iTrackSelectionList[i].iTsDecNode != NULL)
   6847         {
   6848             // Call Init() on the dec node
   6849             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iTrackSelectionList[i].iTsDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_DecNodeInit);
   6850 
   6851             leavecode = IssueDecNodeInit(iTrackSelectionList[i].iTsDecNode, iTrackSelectionList[i].iTsDecNodeSessionId, (OsclAny*) context, cmdid);
   6852 
   6853             if (cmdid != -1 && leavecode == 0)
   6854             {
   6855                 ++iNumPendingNodeCmd;
   6856             }
   6857             else
   6858             {
   6859                 FreeEngineContext(context);
   6860                 return PVMFFailure;
   6861             }
   6862         }
   6863     }
   6864 
   6865     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeInit() Out"));
   6866     return PVMFSuccess;
   6867 }
   6868 
   6869 PVMFStatus PVPlayerEngine::DoSourceNodeTrackSelection(PVCommandId /*aCmdId*/, OsclAny* /*aCmdContext*/)
   6870 {
   6871     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() In"));
   6872 
   6873     if (iSourceNodeTrackSelIF == NULL)
   6874     {
   6875         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() Source node track sel IF not available."));
   6876         return PVMFFailure;
   6877     }
   6878 
   6879     //populate playable list first
   6880     PVMFStatus retval = DoTrackSelection(true, false);
   6881     if (retval != PVMFSuccess)
   6882     {
   6883         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() DoTrackSelection - Populating playable list Failed"));
   6884         return retval;
   6885     }
   6886 
   6887     bool usepreferencelist = false;
   6888     if (iTrackSelectionHelper != NULL)
   6889     {
   6890         PVMFMediaPresentationInfo localList;
   6891         iPreferenceList.Reset();
   6892         localList.setPresentationType(iPlayableList.getPresentationType());
   6893         localList.setSeekableFlag(iPlayableList.IsSeekable());
   6894         localList.SetDurationAvailable(iPlayableList.IsDurationAvailable());
   6895         localList.setDurationValue(iPlayableList.getDurationValue());
   6896         localList.setDurationTimeScale(iPlayableList.getDurationTimeScale());
   6897         //if track selection helper is present, it means that
   6898         //user of engine wants to provide inputs
   6899         //the reason we use a local list instead of iPreferenceList is
   6900         //due to memory consideration. This call to "SelectTracks" goes
   6901         //to the app and the app allocates memory to populate the local list
   6902         //This memory needs to be released right away. So we make a copy
   6903         //and release the memory for local list.
   6904         PVMFStatus status =
   6905             iTrackSelectionHelper->SelectTracks(iPlayableList, localList);
   6906         if ((status == PVMFSuccess) &&
   6907                 (localList.getNumTracks() != 0))
   6908         {
   6909             usepreferencelist = true;
   6910             iPreferenceList = localList;
   6911         }
   6912         //release memory now that we have made a copy
   6913         iTrackSelectionHelper->ReleasePreferenceList(localList);
   6914         //else user made no choice, use playable list
   6915     }
   6916 
   6917     retval = DoTrackSelection(false, usepreferencelist);
   6918     if (retval != PVMFSuccess)
   6919     {
   6920         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() DoTrackSelection - TrackSelection Failed"));
   6921         return retval;
   6922     }
   6923 
   6924     uint32 i = 0;
   6925 
   6926     // Create a selected track list
   6927     PVMFMediaPresentationInfo selectedtracks;
   6928     for (i = 0; i < iDatapathList.size(); ++i)
   6929     {
   6930         if (iDatapathList[i].iTrackInfo != NULL)
   6931         {
   6932             selectedtracks.addTrackInfo(*(iDatapathList[i].iTrackInfo));
   6933         }
   6934     }
   6935 
   6936     // Check that at least one track was selected
   6937     if (selectedtracks.getNumTracks() == 0)
   6938     {
   6939         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() No tracks were selected"));
   6940         // @TODO Provide a more specific error info
   6941         return PVMFErrResourceConfiguration;
   6942     }
   6943 
   6944     // Select in source node
   6945     retval = iSourceNodeTrackSelIF->SelectTracks(selectedtracks);
   6946     if (retval != PVMFSuccess)
   6947     {
   6948         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() SelectTracks() on source node failed"));
   6949         return retval;
   6950     }
   6951 
   6952     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() Out"));
   6953     return retval;
   6954 }
   6955 
   6956 PVMFStatus PVPlayerEngine::DoTrackSelection(bool oPopulatePlayableListOnly, bool oUsePreferenceList)
   6957 {
   6958     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoTrackSelection() In"));
   6959 
   6960     if (iSourceNodeTrackSelIF == NULL)
   6961     {
   6962         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoTrackSelection() Source node track sel IF not available."));
   6963         return PVMFFailure;
   6964     }
   6965 
   6966     PVMFMediaPresentationInfo sourcepresinfo;
   6967     if (oPopulatePlayableListOnly)
   6968     {
   6969         // use already saved presentation info list from source node
   6970         sourcepresinfo = iSourcePresInfoList;
   6971 
   6972         iPlayableList.Reset();
   6973 
   6974         iPlayableList.setPresentationType(iSourcePresInfoList.getPresentationType());
   6975         iPlayableList.setSeekableFlag(iSourcePresInfoList.IsSeekable());
   6976         iPlayableList.SetDurationAvailable(iSourcePresInfoList.IsDurationAvailable());
   6977         iPlayableList.setDurationValue(iSourcePresInfoList.getDurationValue());
   6978         iPlayableList.setDurationTimeScale(iSourcePresInfoList.getDurationTimeScale());
   6979     }
   6980     else
   6981     {
   6982         if (oUsePreferenceList)
   6983         {
   6984             //perform track selection based on playable list
   6985             sourcepresinfo = iPreferenceList;
   6986         }
   6987         else
   6988         {
   6989             //perform track selection based on playable list
   6990             sourcepresinfo = iPlayableList;
   6991         }
   6992     }
   6993 
   6994     PVMFStatus retVal = PVMFSuccess;
   6995     uint32 i = 0;
   6996     uint32 k = 0;
   6997 
   6998     if (oPopulatePlayableListOnly)
   6999     {
   7000         for (i = 0; i < iDatapathList.size(); i++)
   7001         {
   7002             // Destroy the track info if present
   7003             if (iDatapathList[i].iTrackInfo)
   7004             {
   7005                 OSCL_DELETE(iDatapathList[i].iTrackInfo);
   7006                 iDatapathList[i].iTrackInfo = NULL;
   7007             }
   7008         }
   7009 
   7010         for (i = 0; i < sourcepresinfo.getNumTracks(); i++)
   7011         {
   7012             PVMFStatus checkcodec = PVMFFailure;
   7013             int32 trackId = -1;
   7014 
   7015             // Go through each track, check codec type, and save the track info
   7016             PVMFTrackInfo* curtrack = sourcepresinfo.getTrackInfo(i);
   7017             trackId = curtrack->getTrackID();
   7018 
   7019             // check if this track can be directly pushed in playable list. This will be the case where decoder node is not needed
   7020             // and Sink node supports the format and format specific info. OR
   7021             // The track is a text track.
   7022 
   7023             if (iTrackSelectionList[i].iTsDecNode == NULL)
   7024             {
   7025                 // check if it is a valid track or not, decoder node can be NULL only in 2 cases
   7026                 // 1) Track can be played without decoder nodes, here iTsTrackValidForPlayableList should be true OR track is TEXT track
   7027                 // 2) If the track is not valid at all, if this is the case, move onto next track.
   7028 
   7029                 if (iTrackSelectionList[i].iTsTrackValidForPlayableList ||
   7030                         (pv_mime_strcmp(curtrack->getTrackMimeType().get_str(), PVMF_MIME_3GPP_TIMEDTEXT)) == 0)
   7031                 {
   7032                     // this can make directly to the Playable list, since it satisfies condition# 1 above.
   7033                     iPlayableList.addTrackInfo(*curtrack);
   7034                     iTrackSelectionList[i].iTsTrackValidForPlayableList = false;
   7035                     checkcodec = PVMFSuccess;
   7036                 }
   7037             }
   7038             else
   7039             {
   7040                 // if sink node alone does not support this track verify its parameters.
   7041                 retVal = DoVerifyTrackInfo(iTrackSelectionList[i], curtrack, checkcodec);
   7042                 if (retVal != PVMFSuccess)
   7043                     return retVal;
   7044 
   7045                 if (checkcodec == PVMFSuccess)
   7046                 {
   7047                     //add it to playable list
   7048                     iPlayableList.addTrackInfo(*curtrack);
   7049                 }
   7050             }
   7051 
   7052             if (checkcodec != PVMFSuccess && trackId >= 0)
   7053             {
   7054                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoTrackSelection() Bad track config for TrackId=%d", trackId));
   7055                 SendInformationalEvent(PVMFInfoTrackDisable, NULL, (OsclAny*)trackId, NULL, 0);
   7056             }
   7057         }
   7058     }
   7059     else
   7060     {
   7061         for (i = 0; i < sourcepresinfo.getNumTracks(); i++)
   7062         {
   7063             PVMFTrackInfo* curtrack = sourcepresinfo.getTrackInfo(i);
   7064 
   7065             for (k = 0; k < iTrackSelectionList.size(); k++)
   7066             {
   7067                 // check which track is selected by comparing the TrackId
   7068                 int32 trackId = curtrack->getTrackID();
   7069                 if (trackId == iTrackSelectionList[k].iTsTrackID)
   7070                 {
   7071                     for (uint32 j = 0; j < iDatapathList.size(); j++)
   7072                     {
   7073                         // if a track has already been added to the datapath, move onto the next datapath.
   7074                         if (!iDatapathList[j].iTrackInfo)
   7075                         {
   7076                             // check for the corresponding datapath to the track
   7077                             if (iDatapathList[j].iSinkNode == iTrackSelectionList[k].iTsSinkNode)
   7078                             {
   7079                                 if (curtrack->DoesTrackHaveDependency() == true)
   7080                                 {
   7081                                     // Track has dependency, move onto next track
   7082                                     j = iDatapathList.size();
   7083                                     k = iTrackSelectionList.size();
   7084                                 }
   7085                                 else
   7086                                 {
   7087                                     // The track has been added to the final list, this means that this track is valid
   7088                                     // and will make to DatapathList and all other video decoders will be destroyed.
   7089                                     iDatapathList[j].iTrackInfo = OSCL_NEW(PVMFTrackInfo, (*curtrack));
   7090 
   7091                                     // set the decoder node, its session id and decoder cap&config IF in the Datapath, since the track is the
   7092                                     // selected one.
   7093                                     if (iTrackSelectionList[k].iTsDecNode)
   7094                                     {
   7095                                         iDatapathList[j].iDecNode = iTrackSelectionList[k].iTsDecNode;
   7096                                         iDatapathList[j].iDecNodeSessionId = iTrackSelectionList[k].iTsDecNodeSessionId;
   7097                                         iDatapathList[j].iDecNodeCapConfigIF = iTrackSelectionList[k].iTsDecNodeCapConfigIF;
   7098                                     }
   7099 
   7100                                     iTrackSelectionList[k].iTsSinkNode = NULL;
   7101                                     iTrackSelectionList[k].iTsSinkNodeSessionId = 0;
   7102                                     iTrackSelectionList[k].iTsSinkNodeCapConfigIF = NULL;
   7103 
   7104                                     iTrackSelectionList[k].iTsDecNode = NULL;
   7105                                     iTrackSelectionList[k].iTsDecNodeSessionId = 0;
   7106                                     iTrackSelectionList[k].iTsDecNodeCapConfigIF = NULL;
   7107                                     iTrackSelectionList[k].iTsDecNodePVInterfaceCapConfig = NULL;
   7108 
   7109                                     iTrackSelectionList[k].iTsTrackID = -1;
   7110                                     iTrackSelectionList[k].iTsTrackValidForPlayableList = false;
   7111                                 }
   7112                                 j = iDatapathList.size();
   7113                             }
   7114                             // Datapath sinknode does not match, check the next datapath for the track
   7115                         }
   7116                         // a track has already been assigned for the datapath, check next datapath for the track
   7117                     }
   7118                     k = iTrackSelectionList.size();
   7119                 }
   7120                 // The trackId of the track does not match with the track in the List, check the next track.
   7121             }
   7122         }
   7123 
   7124         // Go through the track selection list and set similar decoder nodes to NULL. There should be only 1 entry
   7125         // of a decoder node either in DatapathList (this will be for the final playable track) or in
   7126         // TrackSelectionList which will be for tracks which will not be used for playback.
   7127         for (i = 0; i < iTrackSelectionList.size(); i++)
   7128         {
   7129             PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
   7130             for (uint32 j = i + 1; j < iTrackSelectionList.size(); j++)
   7131             {
   7132                 PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(j);
   7133                 if (!(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())))
   7134                 {
   7135                     iTrackSelectionList[j].iTsDecNode = NULL;
   7136                     iTrackSelectionList[j].iTsDecNodeSessionId = 0;
   7137                     iTrackSelectionList[j].iTsDecNodeCapConfigIF = NULL;
   7138                 }
   7139             }
   7140         }
   7141 
   7142         // now go through whole TrackSelectionList and look for similar sink and decoder nodes
   7143         // to the track selected i.e. added to datapath, set all sink and decoder nodes to NULL for the track selected
   7144         for (k = 0; k < iDatapathList.size(); k++)
   7145         {
   7146             for (uint32 s = 0; s < iTrackSelectionList.size(); s++)
   7147             {
   7148                 if ((iDatapathList[k].iSinkNode == iTrackSelectionList[s].iTsSinkNode))
   7149                 {
   7150                     iTrackSelectionList[s].iTsSinkNode = NULL;
   7151                     iTrackSelectionList[s].iTsSinkNodeSessionId = 0;
   7152                     iTrackSelectionList[s].iTsSinkNodeCapConfigIF = NULL;
   7153                 }
   7154 
   7155                 if ((iDatapathList[k].iDecNode != NULL) &&
   7156                         (iDatapathList[k].iDecNode == iTrackSelectionList[s].iTsDecNode))
   7157                 {
   7158                     iTrackSelectionList[s].iTsDecNode = NULL;
   7159                     iTrackSelectionList[s].iTsDecNodeSessionId = 0;
   7160                     iTrackSelectionList[s].iTsDecNodeCapConfigIF = NULL;
   7161                     iTrackSelectionList[s].iTsDecNodePVInterfaceCapConfig = NULL;
   7162                 }
   7163 
   7164                 iTrackSelectionList[s].iTsTrackID = -1;
   7165                 iTrackSelectionList[s].iTsTrackValidForPlayableList = false;
   7166             }
   7167         }
   7168     }
   7169     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoTrackSelection() Out"));
   7170     return retVal;
   7171 }
   7172 
   7173 PVMFStatus PVPlayerEngine::DoVerifyTrackInfo(PVPlayerEngineTrackSelection &aTrackSelection, PVMFTrackInfo* aTrack, PVMFStatus& aCheckcodec)
   7174 {
   7175     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyTrackInfo() In %s", aTrack->getTrackMimeType().get_cstr()));
   7176 
   7177     PVMFStatus status = PVMFSuccess;
   7178     OsclMemAllocator alloc;
   7179     PvmiKvp kvp;
   7180     kvp.key = NULL;
   7181 
   7182     const char* aFormatValType = PVMF_FORMAT_SPECIFIC_INFO_KEY;
   7183     OsclRefCounterMemFrag aConfig;
   7184 
   7185     kvp.length = oscl_strlen(aFormatValType) + 1; // +1 for \0
   7186     kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
   7187     if (kvp.key == NULL)
   7188     {
   7189         return PVMFErrNoMemory;
   7190     }
   7191     oscl_strncpy(kvp.key, aFormatValType, kvp.length);
   7192     aConfig = aTrack->getTrackConfigInfo();
   7193     kvp.value.key_specific_value = (OsclAny*)(aConfig.getMemFragPtr());
   7194     kvp.capacity = aConfig.getMemFragSize();
   7195 
   7196     //Check if we have decoder node cap-config
   7197     if (aTrackSelection.iTsDecNodeCapConfigIF != NULL)
   7198     {
   7199         PVMFFormatType DecnodeFormatType = aTrack->getTrackMimeType().get_str();
   7200 
   7201         PvmiKvp* iErrorKVP = NULL;
   7202         PvmiKvp iKVPSetFormat;
   7203         iKVPSetFormat.key = NULL;
   7204         OSCL_StackString<64> iKeyStringSetFormat;
   7205         iKVPSetFormat.value.pChar_value = (char*)DecnodeFormatType.getMIMEStrPtr();
   7206 
   7207         // Query for video decoder first with the track, if no success, then check for audio decoder. Only one query will succeed.
   7208         // If both fails, check the status.
   7209         iKeyStringSetFormat = _STRLIT_CHAR(PVMF_VIDEO_DEC_FORMAT_TYPE_VALUE_KEY);
   7210         iKVPSetFormat.key = iKeyStringSetFormat.get_str();
   7211 
   7212         aTrackSelection.iTsDecNodeCapConfigIF->setParametersSync(NULL, &iKVPSetFormat, 1, iErrorKVP);
   7213         if (iErrorKVP == NULL)
   7214         {
   7215             //verify codec specific info
   7216             int32 leavecode = 0;
   7217             OSCL_TRY(leavecode, aCheckcodec = aTrackSelection.iTsDecNodeCapConfigIF->verifyParametersSync(NULL, &kvp, 1));
   7218             OSCL_FIRST_CATCH_ANY(leavecode,
   7219                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() unsupported verifyParametersSync did a leave!"));
   7220                                  alloc.deallocate((OsclAny*)(kvp.key));
   7221                                  aCheckcodec = PVMFSuccess; // set it success in case track selection info is not yet available;
   7222                                  return PVMFSuccess;);
   7223 
   7224             if (aCheckcodec != PVMFSuccess)
   7225             {
   7226                 alloc.deallocate((OsclAny*)(kvp.key));
   7227                 //In case of other error code, this is operation error.
   7228                 if (aCheckcodec != PVMFErrNotSupported)
   7229                 {
   7230                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on decoder node failed"));
   7231                     return aCheckcodec;
   7232                 }
   7233                 return status;
   7234             }
   7235 
   7236             int numKvp = 0;
   7237             PvmiKvp* kvpPtr;
   7238             // Query using get
   7239             OSCL_StackString<64> querykey;
   7240 
   7241             querykey = _STRLIT_CHAR("x-pvmf/video/render");
   7242             if (aTrackSelection.iTsDecNodeCapConfigIF->getParametersSync(NULL, querykey.get_str(), kvpPtr, numKvp, NULL) == PVMFSuccess)
   7243             {
   7244                 //verify width/height
   7245                 if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
   7246                     aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, kvpPtr, numKvp);
   7247                 status = aTrackSelection.iTsDecNodeCapConfigIF->releaseParameters(NULL, kvpPtr, numKvp);
   7248             }
   7249         }
   7250         else
   7251         {
   7252             // Query failed for video decoder next try the audio decoder.
   7253             iErrorKVP = NULL;
   7254             iKeyStringSetFormat = NULL;
   7255             iKVPSetFormat.key = NULL;
   7256 
   7257             iKeyStringSetFormat += _STRLIT_CHAR(PVMF_AUDIO_DEC_FORMAT_TYPE_VALUE_KEY);
   7258             iKVPSetFormat.key = iKeyStringSetFormat.get_str();
   7259 
   7260             aTrackSelection.iTsDecNodeCapConfigIF->setParametersSync(NULL, &iKVPSetFormat, 1, iErrorKVP);
   7261 
   7262             if (iErrorKVP == NULL)
   7263             {
   7264                 //verify codec specific info
   7265                 int32 leavecodeaudio = 0;
   7266                 OSCL_TRY(leavecodeaudio, aCheckcodec = aTrackSelection.iTsDecNodeCapConfigIF->verifyParametersSync(NULL, &kvp, 1));
   7267                 OSCL_FIRST_CATCH_ANY(leavecodeaudio,
   7268                                      PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() unsupported verifyParametersSync did a leave!"));
   7269                                      alloc.deallocate((OsclAny*)(kvp.key));
   7270                                      aCheckcodec = PVMFSuccess; // set it success in case track selection info is not yet available;
   7271                                      return PVMFSuccess;);
   7272 
   7273                 if (aCheckcodec != PVMFSuccess)
   7274                 {
   7275                     alloc.deallocate((OsclAny*)(kvp.key));
   7276                     //In case of other error code, this is operation error.
   7277                     if (aCheckcodec != PVMFErrNotSupported)
   7278                     {
   7279                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on decoder node failed"));
   7280                         return aCheckcodec;
   7281                     }
   7282                     return status;
   7283                 }
   7284 
   7285                 int numKvp = 0;
   7286                 PvmiKvp* kvpPtr;
   7287                 // Query using get
   7288                 OSCL_StackString<64> querykey;
   7289 
   7290                 querykey = _STRLIT_CHAR("x-pvmf/audio/render");
   7291                 if (aTrackSelection.iTsDecNodeCapConfigIF->getParametersSync(NULL, querykey.get_str(), kvpPtr, numKvp, NULL) == PVMFSuccess)
   7292                 {
   7293                     //verify samplerate and channels
   7294                     if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
   7295                         aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, kvpPtr, numKvp);
   7296                     status = aTrackSelection.iTsDecNodeCapConfigIF->releaseParameters(NULL, kvpPtr, numKvp);
   7297                 }
   7298             }
   7299         }
   7300     }
   7301     else
   7302     {
   7303         if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
   7304         {
   7305             aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, &kvp, 1);
   7306         }
   7307     }
   7308 
   7309     alloc.deallocate((OsclAny*)(kvp.key));
   7310     if (aCheckcodec != PVMFSuccess)
   7311     {
   7312         //In case of other error code, this is operation error.
   7313         if (aCheckcodec != PVMFErrNotSupported)
   7314         {
   7315             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on sink node failed"));
   7316             return aCheckcodec;
   7317         }
   7318         return status;
   7319     }
   7320 
   7321     //verify bitrate
   7322     PvmiKvp iKVPBitRate;
   7323     iKVPBitRate.key = NULL;
   7324 
   7325     OSCL_StackString<64> iKVPStringBitRate = _STRLIT_CHAR(PVMF_BITRATE_VALUE_KEY);
   7326     iKVPBitRate.key = iKVPStringBitRate.get_str();
   7327     iKVPBitRate.value.uint32_value = aTrack->getTrackBitRate();
   7328 
   7329     if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
   7330         aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, &iKVPBitRate, 1);
   7331     //In case of other error code,