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, this is operation error.
   7332     if (aCheckcodec != PVMFSuccess)
   7333     {
   7334         //In case of other error code, this is operation error.
   7335         if (aCheckcodec != PVMFErrNotSupported)
   7336         {
   7337             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on sinknode bitrate failed"));
   7338             return aCheckcodec;
   7339         }
   7340         return status;
   7341     }
   7342 
   7343     //verify video framerate, if track is not video, sink will return ErrNotSupported.
   7344     if (aTrack->getTrackFrameRate() > 0)
   7345     {
   7346         PvmiKvp iKVPFrameRate;
   7347         iKVPFrameRate.key = NULL;
   7348 
   7349         OSCL_StackString<64> iKVPStringFrameRate = _STRLIT_CHAR(PVMF_FRAMERATE_VALUE_KEY);
   7350         iKVPFrameRate.key = iKVPStringFrameRate.get_str();
   7351         iKVPFrameRate.value.uint32_value = aTrack->getTrackFrameRate();
   7352 
   7353         if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
   7354             aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, &iKVPFrameRate, 1);
   7355         //In case of other error code, this is operation error.
   7356         if (aCheckcodec != PVMFErrNotSupported && aCheckcodec != PVMFSuccess)
   7357         {
   7358             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on sink node framerate failed"));
   7359             return aCheckcodec;
   7360         }
   7361     }
   7362 
   7363     return status;
   7364 }
   7365 
   7366 PVMFStatus PVPlayerEngine::DoSinkNodeDecNodeReset(PVCommandId aCmdId, OsclAny* aCmdContext)
   7367 {
   7368     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   7369                     (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Tick=%d", OsclTickCount::TickCount()));
   7370 
   7371     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() In"));
   7372 
   7373     iNumPendingNodeCmd = 0;
   7374     PVMFCommandId cmdid = -1;
   7375     int32 leavecode = 0;
   7376 
   7377     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   7378     {
   7379         if (iDatapathList[i].iSinkNode != NULL)
   7380         {
   7381             // Call Reset() on the sink node
   7382             PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeDecNodeReset);
   7383 
   7384             leavecode = IssueSinkNodeReset(&(iDatapathList[i]), (OsclAny*) context, cmdid);
   7385 
   7386             if (cmdid != -1 && leavecode == 0)
   7387             {
   7388                 ++iNumPendingNodeCmd;
   7389             }
   7390             else
   7391             {
   7392                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Reset on sink node leaved, asserting"));
   7393                 FreeEngineContext(context);
   7394                 OSCL_ASSERT(false);
   7395             }
   7396         }
   7397 
   7398         if (iDatapathList[i].iDecNode != NULL)
   7399         {
   7400             // Call Reset() on the dec node
   7401             PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeDecNodeReset);
   7402 
   7403             leavecode = IssueDecNodeReset(iDatapathList[i].iDecNode, iDatapathList[i].iDecNodeSessionId, (OsclAny*) context, cmdid);
   7404 
   7405             if (cmdid != -1 && leavecode == 0)
   7406             {
   7407                 ++iNumPendingNodeCmd;
   7408             }
   7409             else
   7410             {
   7411                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Reset on sink node leaved, asserting"));
   7412                 FreeEngineContext(context);
   7413                 OSCL_ASSERT(false);
   7414             }
   7415         }
   7416     }
   7417 
   7418     // There can be some more decoders in TrackSelectionList on which engine needs to call Reset. call Reset on those decoders now.
   7419     for (uint32 j = 0; j < iTrackSelectionList.size(); j++)
   7420     {
   7421         if (iTrackSelectionList[j].iTsDecNode != NULL)
   7422         {
   7423             // Call Reset() on the dec node
   7424             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iTrackSelectionList[j].iTsDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeDecNodeReset);
   7425 
   7426             leavecode = IssueDecNodeReset(iTrackSelectionList[j].iTsDecNode, iTrackSelectionList[j].iTsDecNodeSessionId, (OsclAny*) context, cmdid);
   7427 
   7428             if (cmdid != -1 && leavecode == 0)
   7429             {
   7430                 ++iNumPendingNodeCmd;
   7431             }
   7432             else
   7433             {
   7434                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Reset on sink node leaved, asserting"));
   7435                 FreeEngineContext(context);
   7436                 OSCL_ASSERT(false);
   7437             }
   7438         }
   7439     }
   7440 
   7441     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Out"));
   7442     if (iNumPendingNodeCmd == 0)
   7443     {
   7444         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() No datapath could be prepared!"));
   7445         return PVMFFailure;
   7446     }
   7447     else
   7448     {
   7449         return PVMFSuccess;
   7450     }
   7451 }
   7452 
   7453 PVMFStatus PVPlayerEngine::DoSinkDecCleanupSourcePrepare(PVCommandId aCmdId, OsclAny* aCmdContext)
   7454 {
   7455     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   7456                     (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Tick=%d", OsclTickCount::TickCount()));
   7457 
   7458     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() In"));
   7459 
   7460     uint32 i = 0;
   7461     //Destroy created temporal decoder node and sink node
   7462     for (i = 0; i < iTrackSelectionList.size(); ++i)
   7463     {
   7464         if (iTrackSelectionList[i].iTsDecNode != NULL)
   7465         {
   7466             if (iTrackSelectionList[i].iTsDecNodeCapConfigIF)
   7467                 iTrackSelectionList[i].iTsDecNodeCapConfigIF = NULL;
   7468             PVMFStatus status = PVMFFailure;
   7469             status = iTrackSelectionList[i].iTsDecNode->Disconnect(iTrackSelectionList[i].iTsDecNodeSessionId);
   7470             if (status == PVMFFailure)
   7471             {
   7472                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on dec node Failed"));
   7473                 OSCL_ASSERT(false);
   7474             }
   7475             status = iTrackSelectionList[i].iTsDecNode->ThreadLogoff();
   7476             if (status == PVMFFailure)
   7477             {
   7478                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on dec node Failed"));
   7479                 OSCL_ASSERT(false);
   7480             }
   7481             PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
   7482             for (; iter != iNodeUuids.end(); ++iter)
   7483                 if (iter->iNode == iTrackSelectionList[i].iTsDecNode)
   7484                     break;
   7485 
   7486             if (iter != iNodeUuids.end())
   7487             {
   7488                 bool release_status = false;
   7489 
   7490                 release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, iTrackSelectionList[i].iTsDecNode);
   7491                 if (release_status == false)
   7492                 {
   7493                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Factory returned false while releasing the decnode"));
   7494                     OSCL_ASSERT(false);
   7495                     return PVMFFailure;
   7496                 }
   7497 
   7498                 iNodeUuids.erase(iter);
   7499                 iTrackSelectionList[i].iTsDecNode = NULL;
   7500             }
   7501             else
   7502             {
   7503                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() decnode not found"));
   7504                 return PVMFFailure;
   7505             }
   7506         }
   7507         if (iTrackSelectionList[i].iTsSinkNode != NULL)
   7508         {
   7509             for (uint32 j = 0; j < iDatapathList.size(); j++)
   7510             {
   7511                 if (iDatapathList[j].iSinkNode == iTrackSelectionList[i].iTsSinkNode)
   7512                 {
   7513                     PVMFStatus status = PVMFFailure;
   7514                     status = iDatapathList[j].iSinkNode->Disconnect(iDatapathList[j].iSinkNodeSessionId);
   7515                     if (status == PVMFFailure)
   7516                     {
   7517                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on sink node Failed"));
   7518                         OSCL_ASSERT(false);
   7519                     }
   7520                     status = iDatapathList[j].iSinkNode->ThreadLogoff();
   7521                     if (status == PVMFFailure)
   7522                     {
   7523                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on sink node Failed"));
   7524                         OSCL_ASSERT(false);
   7525                     }
   7526                     if (iDatapathList[j].iSinkNodeCapConfigIF)
   7527                         iDatapathList[j].iSinkNodeCapConfigIF = NULL;
   7528                     if (iDatapathList[j].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
   7529                     {
   7530                         PVFileOutputNodeFactory::DeleteFileOutput(iDatapathList[j].iSinkNode);
   7531                         iDatapathList[j].iSinkNode = NULL;
   7532                     }
   7533                     else if (iDatapathList[j].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_SINKNODE)
   7534                     {
   7535                         iDatapathList[j].iSinkNode = NULL;
   7536                     }
   7537                     else
   7538                     {
   7539                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Unsupported player data sink type"));
   7540                         return PVMFFailure;
   7541                     }
   7542                 }
   7543             }
   7544         }
   7545     }
   7546 
   7547     // Also go through the datapathList and if for any datapath TrackInfo is not created, delete that datapath
   7548     for (i = 0; i < iDatapathList.size(); i++)
   7549     {
   7550         if (iDatapathList[i].iTrackInfo == NULL)
   7551         {
   7552             // destroy the sinks first.
   7553             if (iDatapathList[i].iSinkNode != NULL)
   7554             {
   7555                 PVMFStatus status = PVMFFailure;
   7556                 status = iDatapathList[i].iSinkNode->Disconnect(iDatapathList[i].iSinkNodeSessionId);
   7557                 if (status == PVMFFailure)
   7558                 {
   7559                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on sink node Failed"));
   7560                     OSCL_ASSERT(false);
   7561                 }
   7562                 status = iDatapathList[i].iSinkNode->ThreadLogoff();
   7563                 if (status == PVMFFailure)
   7564                 {
   7565                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on sink node Failed"));
   7566                     OSCL_ASSERT(false);
   7567                 }
   7568                 if (iDatapathList[i].iSinkNodeCapConfigIF)
   7569                     iDatapathList[i].iSinkNodeCapConfigIF = NULL;
   7570                 if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
   7571                 {
   7572                     PVFileOutputNodeFactory::DeleteFileOutput(iDatapathList[i].iSinkNode);
   7573                     iDatapathList[i].iSinkNode = NULL;
   7574                 }
   7575                 else if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_SINKNODE)
   7576                 {
   7577                     iDatapathList[i].iSinkNode = NULL;
   7578                 }
   7579                 else
   7580                 {
   7581                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Unsupported player data sink type"));
   7582                     return PVMFFailure;
   7583                 }
   7584             }
   7585 
   7586             // next delete the decoder nodes
   7587             if (iDatapathList[i].iDecNode != NULL)
   7588             {
   7589                 if (iDatapathList[i].iDecNodeCapConfigIF)
   7590                     iDatapathList[i].iDecNodeCapConfigIF = NULL;
   7591                 PVMFStatus status = PVMFFailure;
   7592                 status = iDatapathList[i].iDecNode->Disconnect(iDatapathList[i].iDecNodeSessionId);
   7593                 if (status == PVMFFailure)
   7594                 {
   7595                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on dec node Failed"));
   7596                     OSCL_ASSERT(false);
   7597                 }
   7598                 status = iDatapathList[i].iDecNode->ThreadLogoff();
   7599                 if (status == PVMFFailure)
   7600                 {
   7601                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on dec node Failed"));
   7602                     OSCL_ASSERT(false);
   7603                 }
   7604                 PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
   7605                 for (; iter != iNodeUuids.end(); ++iter)
   7606                     if (iter->iNode == iDatapathList[i].iDecNode)
   7607                         break;
   7608 
   7609                 if (iter != iNodeUuids.end())
   7610                 {
   7611                     bool release_status = false;
   7612 
   7613                     release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, iDatapathList[i].iDecNode);
   7614                     if (release_status == false)
   7615                     {
   7616                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Factory returned false while releasing the decnode"));
   7617                         OSCL_ASSERT(false);
   7618                         return PVMFFailure;
   7619                     }
   7620 
   7621                     iNodeUuids.erase(iter);
   7622                     iDatapathList[i].iDecNode = NULL;
   7623                 }
   7624                 else
   7625                 {
   7626                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() decnode not found"));
   7627                     return PVMFFailure;
   7628                 }
   7629             }
   7630         }
   7631     }
   7632 
   7633     // Reset the Presentation Info list
   7634     iSourcePresInfoList.Reset();
   7635 
   7636     // Clear the Track selection List
   7637     iTrackSelectionList.clear();
   7638 
   7639     PVMFStatus cmdstatus = PVMFFailure;
   7640 
   7641     // Notify the TargetNPT to the source node before calling Prepare.
   7642     if (iSourceNodePBCtrlIF)
   7643     {
   7644         cmdstatus = iSourceNodePBCtrlIF->NotifyTargetPositionSync(iTargetNPT);
   7645     }
   7646     if (cmdstatus == PVMFSuccess || cmdstatus == PVMFErrNotSupported)
   7647     {
   7648         // Prepare the source node
   7649         cmdstatus = DoSourceNodePrepare(aCmdId, aCmdContext);
   7650     }
   7651     if (cmdstatus != PVMFSuccess)
   7652     {
   7653         bool ehPending = CheckForPendingErrorHandlingCmd();
   7654         if (ehPending)
   7655         {
   7656             // there should be no error handling queued.
   7657             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Already EH pending, should never happen"));
   7658             return PVMFPending;
   7659         }
   7660         else
   7661         {
   7662             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   7663                             (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() DoSourceNodePrepare failed, Add EH command"));
   7664             iCommandCompleteErrMsgInErrorHandling = NULL;
   7665             iCommandCompleteStatusInErrorHandling = cmdstatus;
   7666             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   7667         }
   7668         return PVMFFailure;
   7669     }
   7670 
   7671     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Out"));
   7672     return PVMFSuccess;
   7673 }
   7674 
   7675 PVMFStatus PVPlayerEngine::DoSourceNodePrepare(PVCommandId aCmdId, OsclAny* aCmdContext)
   7676 {
   7677     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   7678                     (0, "PVPlayerEngine::DoSourceNodePrepare() Tick=%d", OsclTickCount::TickCount()));
   7679 
   7680     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePrepare() In"));
   7681 
   7682     if (iSourceNode == NULL)
   7683     {
   7684         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePrepare() Source node not available."));
   7685         return PVMFFailure;
   7686     }
   7687 
   7688     // If source node is already in Prepared state then don't call Prepare()
   7689     if (iSourceNode->GetState() == EPVMFNodePrepared)
   7690     {
   7691         // Datapaths are already set during intelligent track selection, just query for optional interfaces.
   7692         iNumPendingDatapathCmd = 0;
   7693         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   7694         {
   7695             if (iDatapathList[i].iTrackInfo != NULL)
   7696             {
   7697                 PVMFStatus cmdstatus = DoSinkNodeQueryInterfaceOptional(iDatapathList[i], aCmdId, aCmdContext);
   7698                 if (cmdstatus == PVMFSuccess)
   7699                 {
   7700                     ++iNumPendingDatapathCmd;
   7701                 }
   7702             }
   7703         }
   7704 
   7705         if (iNumPendingDatapathCmd == 0)
   7706         {
   7707             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePrepare() No datapath could be prepared!"));
   7708             return PVMFFailure;
   7709         }
   7710         else
   7711         {
   7712             return PVMFSuccess;
   7713         }
   7714     }
   7715 
   7716     // Call Prepare() on the source node
   7717     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodePrepare);
   7718 
   7719     PVMFCommandId cmdid = -1;
   7720     int32 leavecode = 0;
   7721     OSCL_TRY(leavecode, cmdid = iSourceNode->Prepare(iSourceNodeSessionId, (OsclAny*)context));
   7722     OSCL_FIRST_CATCH_ANY(leavecode,
   7723                          FreeEngineContext(context);
   7724                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePrepare() Prepare on iSourceNode did a leave!"));
   7725                          return PVMFFailure);
   7726 
   7727     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePrepare() Out"));
   7728 
   7729     return PVMFSuccess;
   7730 }
   7731 
   7732 PVMFStatus PVPlayerEngine::DoSinkNodeQueryInterfaceOptional(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   7733 {
   7734     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   7735                     (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
   7736 
   7737     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   7738 
   7739     int32 leavecode = 0;
   7740 
   7741     // Request optional extension interface from the sink node
   7742     PVPlayerEngineContext* context = NULL;
   7743     PVMFCommandId cmdid = -1;
   7744     aDatapath.iNumPendingCmd = 0;
   7745 
   7746     // Request the sync control interface for the sink node
   7747     context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeQuerySyncCtrlIF);
   7748     cmdid = -1;
   7749     leavecode = 0;
   7750     aDatapath.iSinkNodePVInterfaceSyncCtrl = NULL;
   7751     OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->QueryInterface(aDatapath.iSinkNodeSessionId, PvmfNodesSyncControlUuid, aDatapath.iSinkNodePVInterfaceSyncCtrl, (OsclAny*)context));
   7752     if (leavecode)
   7753     {
   7754         aDatapath.iSinkNodePVInterfaceSyncCtrl = NULL;
   7755         FreeEngineContext(context);
   7756         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() QueryInterface on sink node for sync control IF did a leave!"));
   7757     }
   7758     else
   7759     {
   7760         ++aDatapath.iNumPendingCmd;
   7761     }
   7762 
   7763     // Query for Metadata IF
   7764     context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeQueryMetadataIF);
   7765     PVUuid metadatauuid = KPVMFMetadataExtensionUuid;
   7766     cmdid = -1;
   7767     leavecode = 0;
   7768     aDatapath.iSinkNodePVInterfaceMetadataExt = NULL;
   7769     OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->QueryInterface(aDatapath.iSinkNodeSessionId, metadatauuid, aDatapath.iSinkNodePVInterfaceMetadataExt, (OsclAny*)context));
   7770     if (leavecode)
   7771     {
   7772         aDatapath.iSinkNodePVInterfaceMetadataExt = NULL;
   7773         FreeEngineContext(context);
   7774         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() QueryInterface on sink node for metadata IF did a leave!"));
   7775     }
   7776     else
   7777     {
   7778         ++aDatapath.iNumPendingCmd;
   7779     }
   7780 
   7781     if (aDatapath.iNumPendingCmd > 0)
   7782     {
   7783         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() Out"));
   7784         return PVMFSuccess;
   7785     }
   7786     else
   7787     {
   7788         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() Out No pending QueryInterface() on sink node"));
   7789         return PVMFErrNotSupported;
   7790     }
   7791 }
   7792 
   7793 PVMFStatus PVPlayerEngine::DoDecNodeQueryInterfaceOptional(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   7794 {
   7795     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   7796                     (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
   7797 
   7798     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   7799 
   7800     // Check if the dec node is present
   7801     if (aDatapath.iDecNode == NULL)
   7802     {
   7803         return PVMFErrNotSupported;
   7804     }
   7805 
   7806     PVPlayerEngineContext* context = NULL;
   7807     PVMFCommandId cmdid = -1;
   7808     int32 leavecode = 0;
   7809 
   7810     aDatapath.iNumPendingCmd = 0;
   7811 
   7812     // Query for Metadata IF
   7813     context = AllocateEngineContext(&aDatapath, aDatapath.iDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_DecNodeQueryMetadataIF);
   7814     PVUuid metadatauuid = KPVMFMetadataExtensionUuid;
   7815     cmdid = -1;
   7816     leavecode = 0;
   7817     aDatapath.iDecNodePVInterfaceMetadataExt = NULL;
   7818     OSCL_TRY(leavecode, cmdid = aDatapath.iDecNode->QueryInterface(aDatapath.iDecNodeSessionId, metadatauuid, aDatapath.iDecNodePVInterfaceMetadataExt, (OsclAny*)context));
   7819     if (leavecode)
   7820     {
   7821         aDatapath.iDecNodePVInterfaceMetadataExt = NULL;
   7822         FreeEngineContext(context);
   7823         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() QueryInterface on dec node for metadata IF did a leave!"));
   7824     }
   7825     else
   7826     {
   7827         ++aDatapath.iNumPendingCmd;
   7828     }
   7829 
   7830     if (aDatapath.iNumPendingCmd > 0)
   7831     {
   7832         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() Out"));
   7833         return PVMFSuccess;
   7834     }
   7835     else
   7836     {
   7837         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() Out No pending QueryInterface() on dec node"));
   7838         return PVMFErrNotSupported;
   7839     }
   7840 }
   7841 
   7842 
   7843 PVMFStatus PVPlayerEngine::DoDatapathPrepare(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   7844 {
   7845     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   7846                     (0, "PVPlayerEngine::DoDatapathPrepare() for %s Tick=%d",
   7847                      aDatapath.iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   7848 
   7849     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPrepare() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   7850     int32 leavecode = 0;
   7851 
   7852     // Create the datapath utility object
   7853     if (aDatapath.iDatapath == NULL)
   7854     {
   7855         leavecode = 0;
   7856         OSCL_TRY(leavecode, aDatapath.iDatapath = OSCL_NEW(PVPlayerDatapath, ()));
   7857         OSCL_FIRST_CATCH_ANY(leavecode,
   7858                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathPrepare() Could not create datapath object"));
   7859                              return PVMFErrNoMemory);
   7860     }
   7861 
   7862     // Configure the datapath utility based on datapath configuration
   7863     aDatapath.iDatapath->SetObserver(*this, *this, *this);
   7864     aDatapath.iDatapath->SetSourceNode(iSourceNode);
   7865     aDatapath.iDatapath->SetSinkNode(aDatapath.iSinkNode);
   7866 
   7867     if (aDatapath.iDecNode)
   7868     {
   7869         aDatapath.iDatapath->SetDecNode(aDatapath.iDecNode);
   7870         aDatapath.iDatapath->SetSourceDecTrackInfo(*(aDatapath.iTrackInfo));
   7871         aDatapath.iDatapath->SetDecSinkFormatType(aDatapath.iSinkFormat);
   7872     }
   7873     else
   7874     {
   7875         aDatapath.iDatapath->SetSourceSinkTrackInfo(*(aDatapath.iTrackInfo));
   7876     }
   7877 
   7878     // Prepare the datapath
   7879     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPPrepare);
   7880 
   7881     PVMFStatus retval = aDatapath.iDatapath->Prepare((OsclAny*)context);
   7882     if (retval != PVMFSuccess)
   7883     {
   7884         FreeEngineContext(context);
   7885     }
   7886 
   7887     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPrepare() Out"));
   7888     return retval;
   7889 }
   7890 
   7891 
   7892 PVMFStatus PVPlayerEngine::DoSourceNodeQueryDataSourcePosition(PVCommandId aCmdId, OsclAny* aCmdContext)
   7893 {
   7894     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() In"));
   7895 
   7896     // Check if the source node has position control IF
   7897     if (iSourceNodePBCtrlIF == NULL)
   7898     {
   7899         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Playback control IF on source node not available"));
   7900         return PVMFErrNotSupported;
   7901     }
   7902 
   7903     uint32 timems = 0;
   7904     if (iCurrentBeginPosition.iIndeterminate == false)
   7905     {
   7906         // Convert beginning position to milliseconds
   7907         PVMFStatus retval = ConvertToMillisec(iCurrentBeginPosition, timems);
   7908         if (retval != PVMFSuccess)
   7909         {
   7910             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Converting to millisec failed"));
   7911             return retval;
   7912         }
   7913     }
   7914 
   7915     PVMFCommandId cmdid = -1;
   7916 
   7917     if (iSeekToSyncPoint && iSyncPointSeekWindow > 0)
   7918     {
   7919         PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryDataSourcePosition);
   7920 
   7921         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Calling QueryDataSourcePosition() Starting pos %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
   7922         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Calling QueryDataSourcePosition() Starting pos %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
   7923         // As in case of MP4 file we need to call overload function of QueryDataSourcePosition which retruns
   7924         // I frame before and after instead of actaul NPT, format type will be checked here to first find if
   7925         // format-type is one of the MP4 varient
   7926 
   7927         PVMFNodeCapability nodeCapability;
   7928         iSourceNode->GetCapability(nodeCapability);
   7929         PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
   7930         bool mpeg4FormatType = false;
   7931         if (formatType != NULL)
   7932         {
   7933             if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
   7934             {
   7935                 mpeg4FormatType = true;
   7936             }
   7937             else
   7938             {
   7939                 mpeg4FormatType = false;
   7940             }
   7941         }
   7942         int32 leavecode = 0;
   7943         if (mpeg4FormatType)
   7944         {
   7945             OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT,
   7946                                         iSeekPointBeforeTargetNPT, iSeekPointAfterTargetNPT, (OsclAny*) context, iSeekToSyncPoint));
   7947         }
   7948         else
   7949         {
   7950             OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT, iActualNPT,
   7951                                         iSeekToSyncPoint, (OsclAny*)context));
   7952         }
   7953 
   7954         if (leavecode != 0)
   7955         {
   7956             FreeEngineContext(context);
   7957             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() QueryDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
   7958             if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   7959             {
   7960                 // Since position query is not supported, assume the repositioning will
   7961                 // go to the requested position
   7962                 // Do the source positioning
   7963                 return DoSourceNodeSetDataSourcePosition(aCmdId, aCmdContext);
   7964             }
   7965             else
   7966             {
   7967                 return PVMFFailure;
   7968             }
   7969         }
   7970     }
   7971     else
   7972     {
   7973         // Go straight to repositioning the data source
   7974         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition: Straight call SetDataSourcePosition Starting pos %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
   7975         return DoSourceNodeSetDataSourcePosition(aCmdId, aCmdContext);
   7976     }
   7977 
   7978     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Out"));
   7979 
   7980     return PVMFSuccess;
   7981 }
   7982 
   7983 
   7984 PVMFStatus PVPlayerEngine::DoSourceNodeSetDataSourcePosition(PVCommandId aCmdId, OsclAny* aCmdContext)
   7985 {
   7986     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() In"));
   7987 
   7988     // Check if the source node has position control IF
   7989     if (iSourceNodePBCtrlIF == NULL)
   7990     {
   7991         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() Playback control IF on source node not available"));
   7992         // Since repositioning IF is not supported by this source node, assume the playback
   7993         // will start from time 0
   7994         iActualNPT = 0;
   7995         iActualMediaDataTS = 0;
   7996         iSkipMediaDataTS = 0;
   7997         // Then continue to handle like success case
   7998         iStartNPT = 0;
   7999         iStartMediaDataTS = 0;
   8000         // Save the actual starting position for GetPlaybackRange() query
   8001         iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   8002         iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   8003         iTargetNPT = iActualNPT;
   8004 
   8005         // Repositioning so reset the EOS received flag for each active datapath
   8006         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8007         {
   8008             if (iDatapathList[i].iDatapath)
   8009             {
   8010                 iDatapathList[i].iEndOfDataReceived = false;
   8011             }
   8012         }
   8013 
   8014         // Start the source node
   8015         return DoSourceNodeStart(aCmdId, aCmdContext);
   8016     }
   8017 
   8018     // Set the position of the source node
   8019     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourcePosition);
   8020 
   8021     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() Calling SetDataSourcePosition() TargetNPT %d ms, SeekToSyncPoint %d", iTargetNPT, iSeekToSyncPoint));
   8022 
   8023     int32 leavecode = 0;
   8024     PVMFCommandId cmdid = -1;
   8025 
   8026     OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->SetDataSourcePosition(iSourceNodeSessionId, iTargetNPT, iActualNPT, iActualMediaDataTS, iSeekToSyncPoint, iStreamID, (OsclAny*)context));
   8027     OSCL_FIRST_CATCH_ANY(leavecode,
   8028                          FreeEngineContext(context);
   8029                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() SetDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
   8030                          if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   8031 {
   8032     // Since this repositioning was not supported, assume the playback
   8033     // will start from same location as before reposition request.
   8034     PVPPlaybackPosition curpos;
   8035     curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   8036     GetPlaybackClockPosition(curpos);
   8037         uint32 clockcurpos = 0;
   8038         bool tmpbool = false;
   8039         iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   8040 
   8041         // since repositioning is not supported continue playing from current position.
   8042         iWatchDogTimerInterval = 0;
   8043         iActualNPT = curpos.iPosValue.millisec_value;
   8044         iActualMediaDataTS = clockcurpos;
   8045         iSkipMediaDataTS = clockcurpos;
   8046 
   8047         iStartNPT = iActualNPT;
   8048         iStartMediaDataTS = iSkipMediaDataTS;
   8049 
   8050         // also decrement the stream id as no skip will be called on MIO node.
   8051         --iStreamID;
   8052 
   8053         // Save the actual starting position for GetPlaybackRange() query
   8054         iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   8055         iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   8056         iTargetNPT = iActualNPT;
   8057 
   8058         // Repositioning so reset the EOS received flag for each active datapath
   8059         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8060         {
   8061             if (iDatapathList[i].iDatapath)
   8062             {
   8063                 iDatapathList[i].iEndOfDataReceived = false;
   8064             }
   8065         }
   8066 
   8067         // Start the source node
   8068         return DoSourceNodeStart(aCmdId, aCmdContext);
   8069     }
   8070     else
   8071     {
   8072         return PVMFFailure;
   8073     }
   8074                         );
   8075 
   8076     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() Out"));
   8077 
   8078     return PVMFSuccess;
   8079 }
   8080 
   8081 PVMFStatus PVPlayerEngine::DoSourceNodeSetDataSourceDirection(PVCommandId aCmdId, OsclAny* aCmdContext)
   8082 {
   8083     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() In"));
   8084 
   8085     if (iChangePlaybackDirectionWhenResuming)
   8086     {
   8087         //Setting direction during engine Resume, due to a SetPlaybackRate that
   8088         //occurred during engine Paused state.
   8089 
   8090         // Check if the source node has position control IF
   8091         if (iSourceNodeDirCtrlIF == NULL)
   8092         {
   8093             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Direction control IF on source node not available"));
   8094 
   8095             // Since repositioning IF is not supported by this source node, assume the playback
   8096             // will start from time 0
   8097             iActualNPT = 0;
   8098             iActualMediaDataTS = 0;
   8099             iSkipMediaDataTS = 0;
   8100             // Then continue to handle like success case
   8101             iStartNPT = 0;
   8102             iStartMediaDataTS = 0;
   8103             // Save the actual starting position for GetPlaybackRange() query
   8104             iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   8105             iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   8106             iTargetNPT = iActualNPT;
   8107 
   8108             // Repositioning so reset the EOS flag for each active datapath
   8109             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8110             {
   8111                 if (iDatapathList[i].iDatapath)
   8112                 {
   8113                     iDatapathList[i].iEndOfDataReceived = false;
   8114                 }
   8115             }
   8116 
   8117             return PVMFErrNotSupported;
   8118         }
   8119 
   8120         // Set the position of the source node
   8121         PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourceDirection);
   8122 
   8123         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Calling SetDataSourcePosition() "));
   8124 
   8125         int32 leavecode = 0;
   8126         PVMFCommandId cmdid = -1;
   8127         OSCL_TRY(leavecode, cmdid = iSourceNodeDirCtrlIF->SetDataSourceDirection(iSourceNodeSessionId
   8128                                     , (iPlaybackDirection_New < 0) ? PVMF_DATA_SOURCE_DIRECTION_REVERSE : PVMF_DATA_SOURCE_DIRECTION_FORWARD
   8129                                     , iActualNPT
   8130                                     , iActualMediaDataTS
   8131                                     , iOutsideTimebase
   8132                                     , (OsclAny*)context));
   8133         OSCL_FIRST_CATCH_ANY(leavecode,
   8134                              FreeEngineContext(context);
   8135                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() SetDataSourceDirection on iSourceNodeDirCtrlIF did a leave!"));
   8136                              if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   8137     {
   8138         // Since this repositioning was not supported, assume the playback
   8139         // will start from same location as before repos request.
   8140         PVPPlaybackPosition curpos;
   8141         curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   8142         GetPlaybackClockPosition(curpos);
   8143             uint32 clockcurpos = 0;
   8144             bool tmpbool = false;
   8145             iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   8146 
   8147             // since repositioning is not supported continue playing from current position.
   8148             iWatchDogTimerInterval = 0;
   8149             iActualNPT = curpos.iPosValue.millisec_value;
   8150             iActualMediaDataTS = clockcurpos;
   8151             iSkipMediaDataTS = clockcurpos;
   8152 
   8153             iStartNPT = iActualNPT;
   8154             iStartMediaDataTS = iSkipMediaDataTS;
   8155 
   8156             // Save the actual starting position for GetPlaybackRange() query
   8157             iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   8158             iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   8159             iTargetNPT = iActualNPT;
   8160 
   8161             // Repositioning so reset the EOS flag for each active datapath
   8162             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8163             {
   8164                 if (iDatapathList[i].iDatapath)
   8165                 {
   8166                     iDatapathList[i].iEndOfDataReceived = false;
   8167                 }
   8168             }
   8169 
   8170             return PVMFErrNotSupported;
   8171         }
   8172         else
   8173         {
   8174             return PVMFFailure;
   8175         }
   8176                             );
   8177 
   8178         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Out"));
   8179 
   8180         return PVMFSuccess;
   8181     }
   8182     else
   8183     {
   8184         //changing direction during SetPlaybackRate command
   8185 
   8186         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() In"));
   8187 
   8188         // Check if the source node has direction control IF
   8189         if (iSourceNodeDirCtrlIF == NULL)
   8190         {
   8191             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() No source direction control IF"));
   8192             return PVMFFailure;
   8193         }
   8194 
   8195         // Pause the playback clock
   8196         bool clockpausedhere = iPlaybackClock.Pause();
   8197 
   8198         // Set the new direction on the source node
   8199         PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourceDirection);
   8200 
   8201         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Calling SetDataSourceDirection() on source node."));
   8202 
   8203         int32 leavecode = 0;
   8204         PVMFCommandId cmdid = -1;
   8205         OSCL_TRY(leavecode, cmdid = iSourceNodeDirCtrlIF->SetDataSourceDirection(iSourceNodeSessionId
   8206                                     , (iPlaybackDirection_New < 0) ? PVMF_DATA_SOURCE_DIRECTION_REVERSE : PVMF_DATA_SOURCE_DIRECTION_FORWARD
   8207                                     , iActualNPT
   8208                                     , iActualMediaDataTS
   8209                                     , iOutsideTimebase_New
   8210                                     , (OsclAny*)context));
   8211         OSCL_FIRST_CATCH_ANY(leavecode,
   8212                              FreeEngineContext(context);
   8213                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() SetDataSourceDirection on iSourceNodeDirCtrlIF did a leave!"));
   8214                              if (clockpausedhere)
   8215     {
   8216         // Resume the clock if paused in this function
   8217         StartPlaybackClock();
   8218         }
   8219 
   8220         if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
   8221     {
   8222         return leavecode;
   8223     }
   8224     else
   8225     {
   8226         return PVMFFailure;
   8227     }
   8228                         );
   8229 
   8230         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Out"));
   8231 
   8232         return PVMFSuccess;
   8233         //wait on node command complete and a call to HandleSourceNodeSetDataSourceDirection
   8234     }
   8235 }
   8236 
   8237 PVMFStatus PVPlayerEngine::DoSourceNodeStart(PVCommandId aCmdId, OsclAny* aCmdContext)
   8238 {
   8239     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   8240                     (0, "PVPlayerEngine::DoSourceNodeStart() Tick=%d", OsclTickCount::TickCount()));
   8241 
   8242     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStart() In"));
   8243 
   8244     if (iSourceNode == NULL)
   8245     {
   8246         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStart() Source node not available."));
   8247         return PVMFFailure;
   8248     }
   8249 
   8250     // Start the source node
   8251     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeStart);
   8252 
   8253     PVMFCommandId cmdid = -1;
   8254     int32 leavecode = 0;
   8255     OSCL_TRY(leavecode, cmdid = iSourceNode->Start(iSourceNodeSessionId, (OsclAny*)context));
   8256     OSCL_FIRST_CATCH_ANY(leavecode,
   8257                          FreeEngineContext(context);
   8258                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStart() Start on iSourceNode did a leave!"));
   8259                          return PVMFFailure);
   8260 
   8261     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStart() Out"));
   8262 
   8263     return PVMFSuccess;
   8264 }
   8265 
   8266 
   8267 PVMFStatus PVPlayerEngine::DoDatapathStart(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   8268 {
   8269     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   8270                     (0, "PVPlayerEngine::DoDatapathStart() for %s Tick=%d",
   8271                      aDatapath.iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   8272 
   8273     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStart() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   8274 
   8275     // Start the datapath
   8276     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPStart);
   8277 
   8278     PVMFStatus retval = aDatapath.iDatapath->Start((OsclAny*)context);
   8279     if (retval != PVMFSuccess)
   8280     {
   8281         FreeEngineContext(context);
   8282     }
   8283 
   8284     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStart() Out"));
   8285     return retval;
   8286 }
   8287 
   8288 
   8289 PVMFStatus PVPlayerEngine::DoSinkNodeSkipMediaData(PVCommandId aCmdId, OsclAny* aCmdContext)
   8290 {
   8291     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   8292                     (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() Tick=%d", OsclTickCount::TickCount()));
   8293 
   8294     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() In"));
   8295 
   8296     // Tell the sink nodes to skip the unneeded media data
   8297     iNumPendingNodeCmd = 0;
   8298     int32 leavecode = 0;
   8299 
   8300     // Call SkipMediaData() for each active datapath with sink nodes that have the sync control IF
   8301     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8302     {
   8303         if (iDatapathList[i].iDatapath &&
   8304                 iDatapathList[i].iEndOfDataReceived == false &&
   8305                 iDatapathList[i].iSinkNodeSyncCtrlIF)
   8306         {
   8307             PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeSkipMediaData);
   8308 
   8309             leavecode = IssueSinkSkipMediaData(&(iDatapathList[i]), false, (OsclAny*) context);
   8310             if (leavecode == 0)
   8311             {
   8312                 ++iNumPendingNodeCmd;
   8313                 ++iNumPendingSkipCompleteEvent;
   8314                 ++iNumPVMFInfoStartOfDataPending;
   8315             }
   8316             else
   8317             {
   8318                 FreeEngineContext(context);
   8319             }
   8320         }
   8321     }
   8322 
   8323     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() Out"));
   8324     if (iNumPendingNodeCmd > 0)
   8325     {
   8326         return PVMFSuccess;
   8327     }
   8328     else
   8329     {
   8330         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() Skip on sink nodes failed"));
   8331         return PVMFFailure;
   8332     }
   8333 }
   8334 
   8335 
   8336 PVMFStatus PVPlayerEngine::DoStart(PVPlayerEngineCommand& aCmd)
   8337 {
   8338     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   8339                     (0, "PVPlayerEngine::DoStart() Tick=%d", OsclTickCount::TickCount()));
   8340 
   8341     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStart() In, State=%d", iState));
   8342 
   8343     if (GetPVPlayerState() == PVP_STATE_STARTED)
   8344     {
   8345         if (iState == PVP_ENGINE_STATE_AUTO_PAUSED)
   8346         {
   8347             // Engine in AUTO-PAUSED state since it recieved an Underflow event
   8348             // during Prepare. Set the engine state to STARTED and return success
   8349             // Wait for DataReady event for the playback to start.
   8350             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   8351                             (0, "PVPlayerEngine::DoStart() Engine in auto-paused state, set it to started"));
   8352             SetEngineState(PVP_ENGINE_STATE_STARTED);
   8353         }
   8354         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStart() Engine already in Started State"));
   8355         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8356         return PVMFSuccess;
   8357     }
   8358 
   8359     if (iPlaybackPausedDueToEndOfClip)
   8360     {
   8361         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStart() Playback already paused due to End of clip"));
   8362         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8363         return PVMFSuccess;
   8364     }
   8365     if (GetPVPlayerState() != PVP_STATE_PREPARED)
   8366     {
   8367         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStart() Wrong engine state"));
   8368         return PVMFErrInvalidState;
   8369     }
   8370 
   8371     if (iNumPVMFInfoStartOfDataPending == 0)
   8372     {
   8373         // start the clock only if Skip is complete and InfoStartOfData has been received
   8374         // Enable the end time check if specified
   8375         UpdateCurrentEndPosition(iCurrentEndPosition);
   8376         StartPlaybackClock();
   8377     }
   8378     else
   8379     {
   8380         // Sink nodes have not reported InfoStartOfData yet.
   8381         // Check if WatchDogTimer has already been set or not,
   8382         // if Timer has not been set or has expired then set it to a default value timer.
   8383         if (!(iWatchDogTimer->IsBusy()))
   8384         {
   8385             // set a dafault timer
   8386             iWatchDogTimerInterval = 0;
   8387             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   8388                             (0, "PVPlayerEngine::DoStart() Setting WatchDogTimer to a dafult value of 1 second"));
   8389             iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval); // this will set a timer to a default
   8390             iWatchDogTimer->Start();                                  // value of 1 sec. since iWatchDogTimerInterval is zero.
   8391         }
   8392     }
   8393 
   8394     SetEngineState(PVP_ENGINE_STATE_STARTED);
   8395     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8396 
   8397     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStart() Out"));
   8398     return PVMFSuccess;
   8399 }
   8400 
   8401 
   8402 PVMFStatus PVPlayerEngine::DoPause(PVPlayerEngineCommand& aCmd)
   8403 {
   8404     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
   8405                     (0, "PVPlayerEngine::DoPause() Tick=%d", OsclTickCount::TickCount()));
   8406 
   8407     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPause() In"));
   8408 
   8409     // Check engine state
   8410     switch (GetPVPlayerState())
   8411     {
   8412         case PVP_STATE_PAUSED :
   8413             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPause() Engine already in Paused State"));
   8414             EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8415             return PVMFSuccess;
   8416 
   8417         case PVP_STATE_STARTED :
   8418             break;
   8419 
   8420         case PVP_STATE_PREPARED :
   8421             if (aCmd.GetCmdType() == PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP)
   8422             {
   8423                 //It is possible in repositioning to end use-case that
   8424                 //engine receives StartofData and EndofData before Prepare
   8425                 //completes. So we should not fail Pause, just process it.
   8426                 break;
   8427             }
   8428 
   8429         default:
   8430             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Wrong engine state"));
   8431             return PVMFErrInvalidState;
   8432     }
   8433 
   8434     // Send position update to app.
   8435     SendPositionStatusUpdate();
   8436 
   8437     // Stop the end time check timer
   8438     iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   8439 
   8440     // Stop the watchdog timer if active. We will Start the timer again in resume.
   8441     // this should only be done when engine is waiting for StartofData info event
   8442     // after reposition.
   8443     if (iNumPVMFInfoStartOfDataPending > 0)
   8444     {
   8445         if (iWatchDogTimer->IsBusy())
   8446         {
   8447             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   8448                             (0, "PVPlayerEngine::DoPause - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
   8449             iWatchDogTimer->Cancel();
   8450         }
   8451     }
   8452 
   8453     // Pause the clock and notify sinks if not auto-paused
   8454     uint32 i;
   8455     if (iState != PVP_ENGINE_STATE_AUTO_PAUSED)
   8456     {
   8457         // Pause the playback clock
   8458         iPlaybackClock.Pause();
   8459         // Notify data sinks that clock has paused
   8460         for (i = 0; i < iDatapathList.size(); ++i)
   8461         {
   8462             if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   8463             {
   8464                 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStopped();
   8465             }
   8466         }
   8467     }
   8468 
   8469     PVMFStatus retval = PVMFErrNotSupported;
   8470 
   8471     // Issue pause to all active datapaths
   8472     iNumPendingDatapathCmd = 0;
   8473 
   8474     for (i = 0; i < iDatapathList.size(); ++i)
   8475     {
   8476         if (iDatapathList[i].iDatapath)
   8477         {
   8478             if (iState == PVP_ENGINE_STATE_AUTO_PAUSED)
   8479             {
   8480                 // Since sinks are already paused in auto-pause state, skip pausing the sink in the datapath
   8481                 retval = DoDatapathPause(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext(), true);
   8482             }
   8483             else
   8484             {
   8485                 // Pause all nodes in the datapath
   8486                 retval = DoDatapathPause(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext(), false);
   8487             }
   8488 
   8489             if (retval == PVMFSuccess)
   8490             {
   8491                 ++iNumPendingDatapathCmd;
   8492             }
   8493             else
   8494             {
   8495                 bool ehPending = CheckForPendingErrorHandlingCmd();
   8496                 if (ehPending)
   8497                 {
   8498                     // there should be no error handling queued.
   8499                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Already EH pending, should never happen"));
   8500                     return PVMFPending;
   8501                 }
   8502                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() DoDatapathPause Failed, Add EH command"));
   8503                 iCommandCompleteStatusInErrorHandling = retval;
   8504                 iCommandCompleteErrMsgInErrorHandling = NULL;
   8505                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
   8506                 return PVMFPending;
   8507             }
   8508         }
   8509     }
   8510 
   8511     if (iNumPendingDatapathCmd == 0)
   8512     {
   8513         // If there are no active datapaths, continue on to pause the source node
   8514         retval = DoSourceNodePause(aCmd.GetCmdId(), aCmd.GetContext());
   8515     }
   8516 
   8517     if (retval != PVMFSuccess)
   8518     {
   8519         bool ehPending = CheckForPendingErrorHandlingCmd();
   8520         if (ehPending)
   8521         {
   8522             // there should be no error handling queued.
   8523             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Already EH pending, should never happen"));
   8524             return PVMFPending;
   8525         }
   8526         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Pausing datapath and source node failed, Add EH command"));
   8527         iCommandCompleteStatusInErrorHandling = retval;
   8528         iCommandCompleteErrMsgInErrorHandling = NULL;
   8529         AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
   8530         return PVMFPending;
   8531     }
   8532 
   8533     // TEMP Until queued playback range is available
   8534     // Reset the flag when doing a pause
   8535     iChangePlaybackPositionWhenResuming = false;
   8536     iChangePlaybackDirectionWhenResuming = false;
   8537     // END TEMP
   8538 
   8539     SetEngineState(PVP_ENGINE_STATE_PAUSING);
   8540 
   8541     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPause() Out"));
   8542     return PVMFSuccess;
   8543 }
   8544 
   8545 
   8546 PVMFStatus PVPlayerEngine::DoDatapathPause(PVPlayerEngineDatapath& aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext, bool aSinkPaused)
   8547 {
   8548     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   8549                     (0, "PVPlayerEngine::DoDatapathPause() for %s Tick=%d",
   8550                      aDatapath.iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   8551 
   8552     if (aDatapath.iTrackInfo == NULL)
   8553     {
   8554         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathPause() TrackInfo not available, failure"));
   8555         return PVMFFailure;
   8556     }
   8557     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPause() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   8558 
   8559     // Pause the datapath
   8560     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, -1);
   8561 
   8562     PVMFStatus retval = aDatapath.iDatapath->Pause((OsclAny*)context, aSinkPaused);
   8563     if (retval != PVMFSuccess)
   8564     {
   8565         FreeEngineContext(context);
   8566     }
   8567 
   8568     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPause() Out"));
   8569     return retval;
   8570 }
   8571 
   8572 
   8573 PVMFStatus PVPlayerEngine::DoSourceNodePause(PVCommandId aCmdId, OsclAny* aCmdContext)
   8574 {
   8575     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePause() In"));
   8576 
   8577     if (iSourceNode == NULL)
   8578     {
   8579         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePause() Source node not available"));
   8580         return PVMFFailure;
   8581     }
   8582 
   8583     // Pause the source node
   8584     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, -1);
   8585 
   8586     PVMFCommandId cmdid = -1;
   8587     int32 leavecode = 0;
   8588     OSCL_TRY(leavecode, cmdid = iSourceNode->Pause(iSourceNodeSessionId, (OsclAny*)context));
   8589     OSCL_FIRST_CATCH_ANY(leavecode,
   8590                          FreeEngineContext(context);
   8591                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePause() Pause on iSourceNode did a leave!"));
   8592                          return PVMFFailure);
   8593 
   8594     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePause() Out"));
   8595 
   8596     return PVMFSuccess;
   8597 }
   8598 
   8599 
   8600 PVMFStatus PVPlayerEngine::DoResume(PVPlayerEngineCommand& aCmd)
   8601 {
   8602     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoResume() In"));
   8603     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoResume() iNumPendingSkipCompleteEvent: %d", iNumPendingSkipCompleteEvent));
   8604 
   8605     if (GetPVPlayerState() == PVP_STATE_STARTED)
   8606     {
   8607         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Engine already in Started State"));
   8608         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8609         return PVMFSuccess;
   8610     }
   8611 
   8612     // Check engine state
   8613     if (GetPVPlayerState() != PVP_STATE_PAUSED)
   8614     {
   8615         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Wrong engine state"));
   8616         return PVMFErrInvalidState;
   8617     }
   8618 
   8619     // Disallow resume when paused due to EOS and position/direction
   8620     // hasn't been changed
   8621     if (iPlaybackPausedDueToEndOfClip)
   8622     {
   8623         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Currently paused due to EOS so not allowed!"));
   8624         return PVMFErrInvalidState;
   8625     }
   8626 
   8627     PVMFStatus retval;
   8628     if (iChangePlaybackPositionWhenResuming)
   8629     {
   8630         // Reposition occurred during the paused state so need to change the source position first
   8631         retval = DoSourceNodeQueryDataSourcePosition(aCmd.GetCmdId(), aCmd.GetContext());
   8632         // ignore failure, continue on to Start
   8633         if (retval != PVMFSuccess)
   8634         {
   8635             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   8636             PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
   8637             SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
   8638             infomsg->removeRef();
   8639             retval = DoSourceNodeStart(aCmd.GetCmdId(), aCmd.GetContext());
   8640         }
   8641     }
   8642     else if (iChangePlaybackDirectionWhenResuming)
   8643     {
   8644         // Direction change occurred during the paused state so need to change the source direction first
   8645         retval = DoSourceNodeSetDataSourceDirection(aCmd.GetCmdId(), aCmd.GetContext());
   8646         // ignore failure, continue on to Start
   8647         if (retval != PVMFSuccess)
   8648         {
   8649             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   8650             PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
   8651             SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
   8652             infomsg->removeRef();
   8653             retval = DoSourceNodeStart(aCmd.GetCmdId(), aCmd.GetContext());
   8654         }
   8655     }
   8656     else
   8657     {
   8658         retval = DoSourceNodeStart(aCmd.GetCmdId(), aCmd.GetContext());
   8659     }
   8660 
   8661     if (retval != PVMFSuccess)
   8662     {
   8663         bool ehPending = CheckForPendingErrorHandlingCmd();
   8664         if (ehPending)
   8665         {
   8666             // there should be no error handling queued.
   8667             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Already EH pending, should never happen"));
   8668             return PVMFPending;
   8669         }
   8670         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Resuming source node or changing position failed, Add EH command"));
   8671         iCommandCompleteStatusInErrorHandling = retval;
   8672         iCommandCompleteErrMsgInErrorHandling = NULL;
   8673         AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   8674         return PVMFPending;
   8675     }
   8676 
   8677     SetEngineState(PVP_ENGINE_STATE_RESUMING);
   8678 
   8679     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoResume() Out"));
   8680     return PVMFSuccess;
   8681 }
   8682 
   8683 
   8684 PVMFStatus PVPlayerEngine::AddToMetadataInterfaceList(PVMFMetadataExtensionInterface* aMetadataIF, PVMFSessionId aSessionId, PVPlayerEngineDatapath* aEngineDatapath, PVMFNodeInterface* aNode)
   8685 {
   8686     // Validate the interface ptr
   8687     if (aMetadataIF == NULL)
   8688     {
   8689         return PVMFErrArgument;
   8690     }
   8691 
   8692     // Add the specified interface ptr and session ID to the list
   8693     PVPlayerEngineMetadataIFInfo mdifinfo;
   8694     mdifinfo.iInterface = aMetadataIF;
   8695     mdifinfo.iSessionId = aSessionId;
   8696     mdifinfo.iEngineDatapath = aEngineDatapath;
   8697     mdifinfo.iNode = aNode;
   8698     int32 leavecode = 0;
   8699     OSCL_TRY(leavecode, iMetadataIFList.push_back(mdifinfo));
   8700     OSCL_FIRST_CATCH_ANY(leavecode, return PVMFErrNoMemory);
   8701 
   8702     return PVMFSuccess;
   8703 }
   8704 
   8705 PVMFStatus PVPlayerEngine::RemoveFromMetadataInterfaceList(PVMFMetadataExtensionInterface* aMetadataIF, PVMFSessionId aSessionId)
   8706 {
   8707     // Validate the interface ptr
   8708     if (aMetadataIF == NULL)
   8709     {
   8710         return PVMFErrArgument;
   8711     }
   8712 
   8713     // Go through the list to find the specified entry
   8714     for (uint32 i = 0; i < iMetadataIFList.size(); ++i)
   8715     {
   8716         if (aMetadataIF == iMetadataIFList[i].iInterface &&
   8717                 aSessionId == iMetadataIFList[i].iSessionId)
   8718         {
   8719             // Found it. Now erase it from the list
   8720             iMetadataIFList.erase(iMetadataIFList.begin() + i);
   8721             return PVMFSuccess;
   8722         }
   8723     }
   8724 
   8725     // If here that means the specified entry wasn't found in the list
   8726     return PVMFErrArgument;
   8727 }
   8728 
   8729 
   8730 PVMFStatus PVPlayerEngine::DoStop(PVPlayerEngineCommand& aCmd)
   8731 {
   8732     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStop() In"));
   8733 
   8734     if (GetPVPlayerState() == PVP_STATE_INITIALIZED)
   8735     {
   8736         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() Engine already in Initialized State"));
   8737         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8738         return PVMFSuccess;
   8739     }
   8740 
   8741     if (GetPVPlayerState() != PVP_STATE_PREPARED &&
   8742             GetPVPlayerState() != PVP_STATE_STARTED &&
   8743             GetPVPlayerState() != PVP_STATE_PAUSED)
   8744     {
   8745         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() Wrong engine state"));
   8746         return PVMFErrInvalidState;
   8747     }
   8748 
   8749     if (iReleaseMetadataValuesPending)
   8750     {
   8751         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   8752                         (0, "PVPlayerEngine::DoStop() Wrong engine Usage, Stop called without releasing metadata values"));
   8753         return PVMFErrReleaseMetadataValueNotDone;
   8754     }
   8755 
   8756     // reset the dataReady event boolean
   8757     iDataReadySent = false;
   8758 
   8759     // reset all repos related variables
   8760     ResetReposVariables(true);
   8761 
   8762     // Stop the playback position status timer
   8763     StopPlaybackStatusTimer();
   8764 
   8765     // Stop the playback clock
   8766     iPlaybackClock.Stop();
   8767     uint32 starttime = 0;
   8768     bool overflow = 0;
   8769     iPlaybackClock.SetStartTime32(starttime, PVMF_MEDIA_CLOCK_MSEC, overflow);
   8770     iPlaybackDirection = 1;
   8771 
   8772     // Reset the begin/end time variables
   8773     iCurrentBeginPosition.iIndeterminate = true;
   8774     iCurrentEndPosition.iIndeterminate = true;
   8775     iQueuedBeginPosition.iIndeterminate = true;
   8776     iQueuedEndPosition.iIndeterminate = true;
   8777 
   8778     // Reset the paused-due-to-EOS flag
   8779     iPlaybackPausedDueToEndOfClip = false;
   8780 
   8781     // Stop the end time check
   8782     if (iEndTimeCheckEnabled)
   8783     {
   8784         iEndTimeCheckEnabled = false;
   8785         iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   8786     }
   8787 
   8788     PVMFStatus retval = PVMFErrNotSupported;
   8789 
   8790     // Start the stopping sequence
   8791     // First stop all the active datapaths
   8792     iNumPendingDatapathCmd = 0;
   8793     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8794     {
   8795         if (iDatapathList[i].iDatapath)
   8796         {
   8797             PVMFStatus retcode = DoDatapathStop(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext());
   8798             if (retcode == PVMFSuccess)
   8799             {
   8800                 ++iNumPendingDatapathCmd;
   8801                 retval = PVMFSuccess;
   8802             }
   8803             else
   8804             {
   8805                 retval = retcode;
   8806                 break;
   8807             }
   8808         }
   8809     }
   8810 
   8811     if (iNumPendingDatapathCmd == 0 && retval == PVMFErrNotSupported)
   8812     {
   8813         // If there are no active datapath, stop the source node
   8814         retval = DoSourceNodeStop(aCmd.GetCmdId(), aCmd.GetContext());
   8815     }
   8816 
   8817     if (retval != PVMFSuccess)
   8818     {
   8819         bool ehPending = CheckForPendingErrorHandlingCmd();
   8820         if (ehPending)
   8821         {
   8822             // there should be no error handling queued.
   8823             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() Already EH pending, should never happen"));
   8824             return PVMFPending;
   8825         }
   8826         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() source node failed, go in Error handling, Add EH command"));
   8827         iCommandCompleteStatusInErrorHandling = retval;
   8828         iCommandCompleteErrMsgInErrorHandling = NULL;
   8829 
   8830         AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   8831         return PVMFPending;
   8832     }
   8833 
   8834     SetEngineState(PVP_ENGINE_STATE_STOPPING);
   8835 
   8836     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStop() Out"));
   8837     return PVMFSuccess;
   8838 }
   8839 
   8840 
   8841 PVMFStatus PVPlayerEngine::DoDatapathStop(PVPlayerEngineDatapath& aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   8842 {
   8843     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStop() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   8844     if (aDatapath.iTrackInfo == NULL)
   8845     {
   8846         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathStop() TrackInfo not available, failure"));
   8847         return PVMFFailure;
   8848     }
   8849 
   8850     // Stop the datapath
   8851     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPStop);
   8852 
   8853     PVMFStatus retval = aDatapath.iDatapath->Stop((OsclAny*)context);
   8854     if (retval != PVMFSuccess)
   8855     {
   8856         FreeEngineContext(context);
   8857     }
   8858 
   8859     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStop() Out"));
   8860     return retval;
   8861 }
   8862 
   8863 
   8864 PVMFStatus PVPlayerEngine::DoSourceNodeStop(PVCommandId aCmdId, OsclAny* aCmdContext)
   8865 {
   8866     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStop() In"));
   8867 
   8868     if (iSourceNode == NULL)
   8869     {
   8870         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStop() Source node not available."));
   8871         return PVMFFailure;
   8872     }
   8873 
   8874     // Stop the source node
   8875     PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, -1);
   8876 
   8877     PVMFCommandId cmdid = -1;
   8878     int32 leavecode = 0;
   8879     OSCL_TRY(leavecode, cmdid = iSourceNode->Stop(iSourceNodeSessionId, (OsclAny*)context));
   8880     OSCL_FIRST_CATCH_ANY(leavecode,
   8881                          FreeEngineContext(context);
   8882                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStop() Stop on iSourceNode did a leave!"));
   8883                          return PVMFFailure);
   8884 
   8885     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStop() Out"));
   8886 
   8887     return PVMFSuccess;
   8888 }
   8889 
   8890 
   8891 PVMFStatus PVPlayerEngine::DoDatapathTeardown(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   8892 {
   8893     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathTeardown() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   8894 
   8895     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPTeardown);
   8896 
   8897     PVMFStatus retval = aDatapath.iDatapath->Teardown((OsclAny*)context);
   8898     if (retval != PVMFSuccess)
   8899     {
   8900         FreeEngineContext(context);
   8901     }
   8902 
   8903     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathTeardown() Out"));
   8904     return retval;
   8905 }
   8906 
   8907 
   8908 PVMFStatus PVPlayerEngine::DoDatapathReset(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   8909 {
   8910     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathReset() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   8911 
   8912     // Reset the datapath
   8913     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPReset);
   8914 
   8915     PVMFStatus retval = aDatapath.iDatapath->Reset((OsclAny*)context);
   8916     if (retval != PVMFSuccess)
   8917     {
   8918         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathReset() Reset failed. Asserting"));
   8919         FreeEngineContext(context);
   8920         OSCL_ASSERT(false);
   8921     }
   8922 
   8923     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathReset() Out"));
   8924     return retval;
   8925 }
   8926 
   8927 
   8928 PVMFStatus PVPlayerEngine::DoRemoveDataSink(PVPlayerEngineCommand& aCmd)
   8929 {
   8930     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSink() In"));
   8931 
   8932     // previously removed, e.g. during error handling ?
   8933     if (iDatapathList.empty() && GetPVPlayerState() == PVP_STATE_IDLE)
   8934     {
   8935         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSink() All sinks were previously deleted"));
   8936         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8937         return PVMFSuccess;
   8938     }
   8939 
   8940     if (GetPVPlayerState() != PVP_STATE_INITIALIZED)
   8941     {
   8942         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSink() Wrong engine state"));
   8943         return PVMFErrInvalidState;
   8944     }
   8945 
   8946     PVPlayerDataSink* datasink = (PVPlayerDataSink*)(aCmd.GetParam(0).pOsclAny_value);
   8947 
   8948     if (datasink == NULL)
   8949     {
   8950         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSink() Passed in parameter invalid"));
   8951         return PVMFErrArgument;
   8952     }
   8953 
   8954     // Find the track that the passed-in sink belongs to
   8955     PVPlayerEngineDatapath* pvpedp = NULL;
   8956     int32 dpindex = -1;
   8957     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8958     {
   8959         if (iDatapathList[i].iDataSink == datasink)
   8960         {
   8961             pvpedp = &(iDatapathList[i]);
   8962             dpindex = i;
   8963             break;
   8964         }
   8965     }
   8966 
   8967     if (pvpedp == NULL || dpindex == -1)
   8968     {
   8969         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSink() Passed in data sink does not match with ones in engine"));
   8970         return PVMFFailure;
   8971     }
   8972     else
   8973     {
   8974         // Cleanup and remove the datapath associated with the data sink from the list
   8975         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoRemoveDataSink() Removing datapath"));
   8976         DoEngineDatapathCleanup(*pvpedp);
   8977 
   8978         iDatapathList.erase(iDatapathList.begin() + dpindex);
   8979     }
   8980 
   8981     EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   8982 
   8983     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSink() Out"));
   8984     return PVMFSuccess;
   8985 }
   8986 
   8987 void PVPlayerEngine::DoRemoveAllSinks()
   8988 {
   8989     // Clean up the datapaths
   8990     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   8991     {
   8992         DoEngineDatapathCleanup(iDatapathList[i]);
   8993     }
   8994     iDatapathList.clear();
   8995     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoRemoveAllSinks() all datapaths removed"));
   8996 }
   8997 
   8998 
   8999 PVMFStatus PVPlayerEngine::DoReset(PVPlayerEngineCommand& aCmd)
   9000 {
   9001     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReset() In"));
   9002 
   9003     // set engine state to Resetting
   9004     SetEngineState(PVP_ENGINE_STATE_RESETTING);
   9005     iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
   9006 
   9007     // reset all repos related variables
   9008     ResetReposVariables(true);
   9009 
   9010     // Stop the playback position status timer
   9011     StopPlaybackStatusTimer();
   9012 
   9013     // Stop the playback clock
   9014     iPlaybackClock.Stop();
   9015     uint32 starttime = 0;
   9016     bool overflow = 0;
   9017     iPlaybackClock.SetStartTime32(starttime, PVMF_MEDIA_CLOCK_MSEC, overflow);
   9018     iPlaybackDirection = 1;
   9019 
   9020     // Reset the begin/end time variables
   9021     iCurrentBeginPosition.iIndeterminate = true;
   9022     iCurrentEndPosition.iIndeterminate = true;
   9023     iQueuedBeginPosition.iIndeterminate = true;
   9024     iQueuedEndPosition.iIndeterminate = true;
   9025 
   9026     // Reset the paused-due-to-EOS flag
   9027     iPlaybackPausedDueToEndOfClip = false;
   9028 
   9029     // Reset the Presentation Info list
   9030     iSourcePresInfoList.Reset();
   9031 
   9032     // Clear the Track selection List
   9033     iTrackSelectionList.clear();
   9034 
   9035     // Stop the end time check
   9036     if (iEndTimeCheckEnabled)
   9037     {
   9038         iEndTimeCheckEnabled = false;
   9039         iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   9040     }
   9041 
   9042     int32 leavecode = 0;
   9043     PVMFStatus status = PVMFSuccess;
   9044 
   9045     if (iSourceNode)
   9046     {
   9047         if (iSourceNode->GetState() != EPVMFNodeCreated)
   9048         {
   9049             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   9050 
   9051             PVMFCommandId cmdid = -1;
   9052             leavecode = 0;
   9053             OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   9054             OSCL_FIRST_CATCH_ANY(leavecode,
   9055 
   9056                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoReset() Reset on iSourceNode did a leave!"));
   9057                                  FreeEngineContext(context);
   9058                                  OSCL_ASSERT(false);
   9059                                  return PVMFFailure);
   9060         }
   9061         else
   9062         {
   9063             // It is assumed that if SourceNode is in created state then datapaths if present,
   9064             // has to be in IDLE State
   9065             if (!iDatapathList.empty())
   9066             {
   9067                 for (uint32 i = 0; i < iDatapathList.size(); ++i)
   9068                 {
   9069                     if (!iDatapathList[i].iDatapath)
   9070                     {
   9071                         if (iDatapathList[i].iDatapath->iState != PVPDP_IDLE)
   9072                         {
   9073                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   9074                                             (0, "PVPlayerEngine::DoReset() Source Node already in created state, Datapath not in idle state, asserting"));
   9075                             OSCL_ASSERT(false);
   9076                         }
   9077                     }
   9078                 }
   9079                 DoRemoveAllSinks();
   9080             }
   9081             if (iDataSource)
   9082             {
   9083                 RemoveDataSourceSync(*iDataSource);
   9084             }
   9085             SetEngineState(PVP_ENGINE_STATE_IDLE);
   9086             EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   9087         }
   9088     }
   9089     else
   9090     {
   9091         if (iDataSource)
   9092         {
   9093             RemoveDataSourceSync(*iDataSource);
   9094         }
   9095         SetEngineState(PVP_ENGINE_STATE_IDLE);
   9096         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   9097     }
   9098 
   9099     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReset() Out"));
   9100     return status;
   9101 }
   9102 
   9103 PVMFStatus PVPlayerEngine::RemoveDataSourceSync(PVPlayerDataSource &aSrc)
   9104 {
   9105     OSCL_UNUSED_ARG(aSrc);
   9106 
   9107     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSourceSync() In"));
   9108 
   9109     // Destroy the source node if present
   9110     DoSourceNodeCleanup();
   9111 
   9112     // Remove Stored KVP Values
   9113     DeleteKVPValues();
   9114 
   9115     // Remove all metadata IF from the list
   9116     iMetadataIFList.clear();
   9117 
   9118     iDataSource = NULL;
   9119 
   9120     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSourceSync() Out"));
   9121     return PVMFSuccess;
   9122 }
   9123 
   9124 
   9125 PVMFStatus PVPlayerEngine::DoRemoveDataSource(PVPlayerEngineCommand& aCmd)
   9126 {
   9127     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSource() In"));
   9128 
   9129     if (GetPVPlayerState() != PVP_STATE_IDLE)
   9130     {
   9131         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSource() called when engine is not in the IDLE state"));
   9132         return PVMFErrInvalidState;
   9133     }
   9134 
   9135     if (iDataSource == NULL) // previously removed, e.g. during errorhandling
   9136     {
   9137         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   9138         return PVMFSuccess;
   9139     }
   9140 
   9141     PVPlayerDataSource* src = (PVPlayerDataSource*)(aCmd.GetParam(0).pOsclAny_value);
   9142 
   9143     if (iDataSource != src || src == NULL)
   9144     {
   9145         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSource() Passed in parameter invalid"));
   9146         return PVMFErrArgument;
   9147     }
   9148 
   9149     PVMFStatus result = RemoveDataSourceSync(*src);
   9150 
   9151     if (result == PVMFSuccess)
   9152         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   9153 
   9154     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSource() Out"));
   9155     return result;
   9156 }
   9157 
   9158 
   9159 PVMFStatus PVPlayerEngine::DoSourceUnderflowAutoPause(PVPlayerEngineCommand& aCmd)
   9160 {
   9161     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() In"));
   9162 
   9163     /*
   9164      * Underflow can happen in the following States
   9165      * Prepared - Use-cases where-in Source Node reports DataReady and goes into
   9166      * underflow immediately when it starts to retrieve data.
   9167      * Started - This will be the most generic use-case where in the source node
   9168      * is retreiving data and because of low bandwidth conditions runs out of data.
   9169      * In such case Source Node will send an Underflow event to Engine.
   9170      * Paused - A rare use-case but can happen. Use-case where Source Node is about
   9171      * to run out of data and just before Source Node sends an Underflow event to
   9172      * engine, user presses Pause on Engine. Engine gets Pause from user and Underflow
   9173      * from Source Node back-to-back.
   9174      */
   9175     bool pauseSinkNodes = false;
   9176 
   9177     switch (iState)
   9178     {
   9179         case PVP_ENGINE_STATE_PREPARED:
   9180             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9181                             (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() in Prepared state"));
   9182             SetEngineState(PVP_ENGINE_STATE_AUTO_PAUSED);
   9183             break;
   9184 
   9185         case PVP_ENGINE_STATE_STARTED:
   9186             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9187                             (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() in Started state"));
   9188             pauseSinkNodes = true;
   9189             break;
   9190 
   9191         case PVP_ENGINE_STATE_PAUSED:
   9192             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9193                             (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() in Paused state"));
   9194             break;
   9195 
   9196         default:
   9197             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   9198                             (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() Invalid state so cancel auto-pause request!"));
   9199             return PVMFErrCancelled;
   9200     }
   9201 
   9202     // Stop the watchdog timer if active. We will Start the timer again in auto-resume.
   9203     // this should only be done when engine is waiting for StartofData info event
   9204     // after reposition.
   9205     if (iNumPVMFInfoStartOfDataPending > 0)
   9206     {
   9207         if (iWatchDogTimer->IsBusy())
   9208         {
   9209             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   9210                             (0, "PVPlayerEngine::DoSourceUnderflowAutoPause - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
   9211             iWatchDogTimer->Cancel();
   9212         }
   9213     }
   9214 
   9215     if (!pauseSinkNodes)
   9216     {
   9217         // Sink nodes already in Paused state or have no data to process, so
   9218         // no need to call Pause on the sink nodes.
   9219         return PVMFErrNotSupported;
   9220     }
   9221 
   9222     // Pause the playback clock
   9223     iPlaybackClock.Pause();
   9224 
   9225     uint32 i;
   9226     // Notify data sinks that clock has paused
   9227     for (i = 0; i < iDatapathList.size(); ++i)
   9228     {
   9229         if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   9230         {
   9231             iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStopped();
   9232         }
   9233     }
   9234 
   9235     PVMFStatus retval = PVMFErrNotSupported;
   9236 
   9237     // Pause all active sink nodes
   9238     iNumPendingDatapathCmd = 0;
   9239     for (i = 0; i < iDatapathList.size(); ++i)
   9240     {
   9241         if (iDatapathList[i].iDatapath)
   9242         {
   9243             retval = DoSinkNodePause(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext());
   9244             if (retval == PVMFSuccess)
   9245             {
   9246                 ++iNumPendingDatapathCmd;
   9247             }
   9248             else
   9249             {
   9250                 break;
   9251             }
   9252         }
   9253     }
   9254 
   9255     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() Out"));
   9256     if (iNumPendingDatapathCmd == 0)
   9257     {
   9258         return PVMFErrNotSupported;
   9259     }
   9260     else
   9261     {
   9262         SetEngineState(PVP_ENGINE_STATE_AUTO_PAUSING);
   9263         return retval;
   9264     }
   9265 }
   9266 
   9267 
   9268 PVMFStatus PVPlayerEngine::DoSourceDataReadyAutoResume(PVPlayerEngineCommand& aCmd)
   9269 {
   9270     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() In"));
   9271 
   9272     // Don't need to worry about transitional states(...ING).
   9273     // Auto-pause/resume cmds are just regular engine cmds and won't be interrupted by normal ones
   9274 
   9275     // Check if Datapaths (Sink Node) are already in Started state.
   9276     bool datapathSinkNodeStarted = false;
   9277     for (uint32 j = 0; j < iDatapathList.size(); j++)
   9278     {
   9279         if (iDatapathList[j].iSinkNode)
   9280         {
   9281             if (iDatapathList[j].iSinkNode->GetState() != EPVMFNodeStarted)
   9282             {
   9283                 // One of the nodes is not in Started state break from the loop
   9284                 // keeping the boolean datapathSinkNodeStaretd as false.
   9285                 datapathSinkNodeStarted = false;
   9286                 break;
   9287             }
   9288             // this will be true only when all Sink Nodes are in started state.
   9289             datapathSinkNodeStarted = true;
   9290         }
   9291     }
   9292 
   9293     // Next check to see if it is any one of the use-cases:
   9294     // Prepare->Underflow->Start->DataReady or
   9295     // Prepare->Underflow->DataReady->Start or
   9296     // Underflow->Pause->Resume->DataReady or
   9297     // Underflow->Pause->SetPlaybackRange->Resume->DataReady
   9298     // These are cases where Sink Nodes are already in Started state and
   9299     // engine might be still waiting for PVMFInfoStartOfData.
   9300     // Here if all PVMFInfoStartofData have not been received yet,
   9301     // then iNumPVMFInfoStartOfDataPending would be non-zero,
   9302     // In few of these usecase, engine starts playback clock in Resume, source nodes are sposed to pause the
   9303     // clock, since they are the ones in underflow. Once source nodes report dataready, engine would
   9304     // already be in STARTED state. So if the clock is still paused, then start it here.
   9305     // Here just send NotSupported so engine can send DataReady Event to the app.
   9306     // and set the watchdog timer which was cancelled when underflow was recieved.
   9307     if (datapathSinkNodeStarted)
   9308     {
   9309         if (iState == PVP_ENGINE_STATE_PREPARED)
   9310         {
   9311             // DataReady recieved during Prepare, Engine just needs to send
   9312             // DataReady event.
   9313             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9314                             (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: DataReady rcvd, Engine in Prepared state"));
   9315         }
   9316         else if (iState == PVP_ENGINE_STATE_STARTED)
   9317         {
   9318             // Usecases for this scenario:
   9319             // Underflow->Pause->Resume->DataReady
   9320             // Underflow->Pause->SetPlaybackRange->Resume->DataReady
   9321             // Prepare->Underflow->Start->DataReady
   9322             // do nothing here
   9323             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9324                             (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: DataReady rcvd, Engine already in Started state"));
   9325         }
   9326         else if (iState == PVP_ENGINE_STATE_AUTO_PAUSED)
   9327         {
   9328             // Change state back to PREPARED, since Underflow and Dataready cancel each other out.
   9329             // Wait for Start command from App to Start the clock and change state to STARTED.
   9330             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9331                             (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: DataReady rcvd in PVP_ENGINE_STATE_AUTO_PAUSED state. Set state back to PREPARED."));
   9332             SetEngineState(PVP_ENGINE_STATE_PREPARED);
   9333         }
   9334         else
   9335         {
   9336             // This should never happen
   9337             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   9338                             (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() Invalid state %d, Sinks in Started state", iState));
   9339             OSCL_ASSERT(false);
   9340         }
   9341 
   9342         if (iNumPVMFInfoStartOfDataPending > 0)
   9343         {
   9344             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   9345                             (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: Clock in Stopped state, waiting for StartofData"));
   9346 
   9347             if (iWatchDogTimerInterval > 0)
   9348             {
   9349                 if (iWatchDogTimer->IsBusy())
   9350                 {
   9351                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   9352                                     (0, "PVPlayerEngine::DoSourceDataReadyAutoResume - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
   9353                     iWatchDogTimer->Cancel();
   9354                 }
   9355 
   9356                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   9357                                 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume Setting WatchDogTimer for %d ms, iNumPVMFInfoStartOfDataPending=%d",
   9358                                  iWatchDogTimerInterval, iNumPVMFInfoStartOfDataPending));
   9359                 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
   9360                 iWatchDogTimer->Start();
   9361             }
   9362         }
   9363         else if ((iNumPVMFInfoStartOfDataPending == 0) && (iState == PVP_ENGINE_STATE_STARTED))
   9364         {
   9365             StartPlaybackClock();
   9366 
   9367             // Notify data sinks that clock has started
   9368             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   9369             {
   9370                 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   9371                 {
   9372                     iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
   9373                 }
   9374             }
   9375         }
   9376         //return PVMFErrNotSupported so the the DataReady can be sent, depending on iDataReadySent flag.
   9377         return PVMFErrNotSupported;
   9378     }
   9379 
   9380     // Next check to see if it is Underflow->Pause->DataReady->Resume usecase.
   9381     // Then we CANNOT start clock in here, because clock is paused by app.
   9382     // After Pause done, the engine is in PAUSED state. By allowing auto-resume only when
   9383     // auto-paused we deal with this usecase ok.
   9384     if (iState != PVP_ENGINE_STATE_AUTO_PAUSED)
   9385     {
   9386         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() Invalid state %d", iState));
   9387         //return PVMFErrNotSupported so the the DataReady can be sent, depending on iDataReadySent flag.
   9388         return PVMFErrNotSupported;
   9389     }
   9390 
   9391     PVMFStatus retval = PVMFErrNotSupported;
   9392 
   9393     // Resume all active sink nodes
   9394     iNumPendingDatapathCmd = 0;
   9395     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   9396     {
   9397         if (iDatapathList[i].iDatapath)
   9398         {
   9399             retval = DoSinkNodeResume(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext());
   9400             if (retval == PVMFSuccess)
   9401             {
   9402                 ++iNumPendingDatapathCmd;
   9403             }
   9404             else
   9405             {
   9406                 break;
   9407             }
   9408         }
   9409     }
   9410 
   9411     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() Out"));
   9412     if (iNumPendingDatapathCmd == 0)
   9413     {
   9414         return PVMFErrNotSupported;
   9415     }
   9416     else
   9417     {
   9418         SetEngineState(PVP_ENGINE_STATE_AUTO_RESUMING);
   9419         return retval;
   9420     }
   9421 }
   9422 
   9423 
   9424 PVMFStatus PVPlayerEngine::DoSinkNodePause(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   9425 {
   9426     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodePause() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   9427 
   9428     if (!(aDatapath.iTrackInfo) || !(aDatapath.iSinkNode))
   9429     {
   9430         return PVMFErrNotSupported;
   9431     }
   9432 
   9433     // Pause the sink node
   9434     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeAutoPause);
   9435 
   9436     PVMFCommandId cmdid = -1;
   9437     int32 leavecode = 0;
   9438     OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->Pause(aDatapath.iSinkNodeSessionId, (OsclAny*)context));
   9439     OSCL_FIRST_CATCH_ANY(leavecode,
   9440                          FreeEngineContext(context);
   9441                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodePause() Pause on sink node did a leave!"));
   9442                          return PVMFFailure);
   9443 
   9444     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodePause() Out"));
   9445 
   9446     return PVMFSuccess;
   9447 }
   9448 
   9449 
   9450 PVMFStatus PVPlayerEngine::DoSinkNodeResume(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
   9451 {
   9452     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeResume() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   9453 
   9454     if (!(aDatapath.iTrackInfo) || !(aDatapath.iSinkNode))
   9455     {
   9456         return PVMFErrNotSupported;
   9457     }
   9458 
   9459     // Start the sink node to resume
   9460     PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeAutoResume);
   9461 
   9462     PVMFCommandId cmdid = -1;
   9463     int32 leavecode = 0;
   9464     OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->Start(aDatapath.iSinkNodeSessionId, (OsclAny*)context));
   9465     OSCL_FIRST_CATCH_ANY(leavecode,
   9466                          FreeEngineContext(context);
   9467                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeResume() Start on sink node did a leave!"));
   9468                          return PVMFFailure);
   9469 
   9470     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeResume() Out"));
   9471 
   9472     return PVMFSuccess;
   9473 }
   9474 
   9475 void PVPlayerEngine::DoEngineDatapathTeardown(PVPlayerEngineDatapath& aDatapath)
   9476 {
   9477     if (aDatapath.iTrackInfo)
   9478     {
   9479         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathTeardown() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   9480     }
   9481     else
   9482     {
   9483         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathTeardown() In"));
   9484     }
   9485 
   9486     if (aDatapath.iDatapath)
   9487     {
   9488         // Shutdown and reset the datapath
   9489         aDatapath.iDatapath->DisconnectNodeSession();
   9490         aDatapath.iDatapath->SetSinkNode(NULL);
   9491         aDatapath.iDatapath->SetDecNode(NULL);
   9492         aDatapath.iDatapath->SetSourceNode(NULL);
   9493     }
   9494 
   9495     if (aDatapath.iSinkNode)
   9496     {
   9497         PVMFStatus status = PVMFFailure;
   9498         status = aDatapath.iSinkNode->Disconnect(aDatapath.iSinkNodeSessionId);
   9499         if (status == PVMFFailure)
   9500         {
   9501             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Disconnect on Sink Node Failed"));
   9502             OSCL_ASSERT(false);
   9503         }
   9504         status = aDatapath.iSinkNode->ThreadLogoff();
   9505         if (status == PVMFFailure)
   9506         {
   9507             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Threadlogoff on SinkNode Failed"));
   9508             OSCL_ASSERT(false);
   9509         }
   9510 
   9511         // Remove sync ctrl IF if available
   9512         if (aDatapath.iSinkNodeSyncCtrlIF)
   9513         {
   9514             aDatapath.iSinkNodeSyncCtrlIF->SetClock(NULL);
   9515             aDatapath.iSinkNodeSyncCtrlIF->removeRef();
   9516             aDatapath.iSinkNodeSyncCtrlIF = NULL;
   9517         }
   9518 
   9519         // Remove metadata IF if available
   9520         if (aDatapath.iSinkNodeMetadataExtIF)
   9521         {
   9522             RemoveFromMetadataInterfaceList(aDatapath.iSinkNodeMetadataExtIF, aDatapath.iSinkNodeSessionId);
   9523             aDatapath.iSinkNodeMetadataExtIF->removeRef();
   9524             aDatapath.iSinkNodeMetadataExtIF = NULL;
   9525         }
   9526 
   9527         // Remove cap-config IF if available
   9528         if (aDatapath.iSinkNodeCapConfigIF)
   9529         {
   9530             aDatapath.iSinkNodeCapConfigIF = NULL;
   9531         }
   9532 
   9533         if (aDatapath.iDataSink)
   9534         {
   9535             if (aDatapath.iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
   9536             {
   9537                 // Remove file output config IF if available
   9538                 if (aDatapath.iSinkNodeFOConfigIF)
   9539                 {
   9540                     aDatapath.iSinkNodeFOConfigIF->removeRef();
   9541                     aDatapath.iSinkNodeFOConfigIF = NULL;
   9542                 }
   9543                 // Delete the sink node since engine created it.
   9544                 PVFileOutputNodeFactory::DeleteFileOutput(aDatapath.iSinkNode);
   9545             }
   9546         }
   9547         aDatapath.iSinkNode = NULL;
   9548     }
   9549 
   9550     if (aDatapath.iDecNode)
   9551     {
   9552         // Remove metadata IF if available
   9553         if (aDatapath.iDecNodeMetadataExtIF)
   9554         {
   9555             RemoveFromMetadataInterfaceList(aDatapath.iDecNodeMetadataExtIF, aDatapath.iDecNodeSessionId);
   9556             aDatapath.iDecNodeMetadataExtIF->removeRef();
   9557             aDatapath.iDecNodeMetadataExtIF = NULL;
   9558         }
   9559 
   9560         // Remove cap-config IF if available
   9561         if (aDatapath.iDecNodeCapConfigIF)
   9562         {
   9563             aDatapath.iDecNodeCapConfigIF = NULL;
   9564         }
   9565 
   9566         PVMFStatus status = PVMFFailure;
   9567         status = aDatapath.iDecNode->Disconnect(aDatapath.iDecNodeSessionId);
   9568         if (status == PVMFFailure)
   9569         {
   9570             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Disconnect on dec node Failed"));
   9571             OSCL_ASSERT(false);
   9572         }
   9573         status = aDatapath.iDecNode->ThreadLogoff();
   9574         if (status == PVMFFailure)
   9575         {
   9576             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() ThreadLogoff on dec node Failed"));
   9577             OSCL_ASSERT(false);
   9578         }
   9579 
   9580         // search for matching uuid entry in list of instantiated nodes
   9581         PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
   9582         for (; iter != iNodeUuids.end(); ++iter)
   9583             if (iter->iNode == aDatapath.iDecNode)
   9584                 break;
   9585 
   9586         if (iter != iNodeUuids.end())
   9587         {
   9588             bool release_status = false;
   9589 
   9590             release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, aDatapath.iDecNode);
   9591 
   9592             if (release_status == false)
   9593             {
   9594                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Factory returned false while releasing the decnode"));
   9595                 return;
   9596             }
   9597 
   9598             iNodeUuids.erase(iter);
   9599             aDatapath.iDecNode = NULL;
   9600         }
   9601         else
   9602         {
   9603             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() decnode not found"));
   9604             return;
   9605         }
   9606     }
   9607 
   9608     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Out"));
   9609 }
   9610 
   9611 
   9612 void PVPlayerEngine::DoEngineDatapathCleanup(PVPlayerEngineDatapath& aDatapath)
   9613 {
   9614     if (aDatapath.iTrackInfo)
   9615     {
   9616         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathCleanup() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
   9617     }
   9618     else
   9619     {
   9620         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathCleanup() In"));
   9621     }
   9622 
   9623     DoEngineDatapathTeardown(aDatapath);
   9624 
   9625     // Destroy the datapath utility object instance
   9626     if (aDatapath.iDatapath)
   9627     {
   9628         OSCL_DELETE(aDatapath.iDatapath);
   9629         aDatapath.iDatapath = NULL;
   9630     }
   9631 
   9632     // Destroy the track info
   9633     if (aDatapath.iTrackInfo)
   9634     {
   9635         OSCL_DELETE(aDatapath.iTrackInfo);
   9636         aDatapath.iTrackInfo = NULL;
   9637     }
   9638 
   9639     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathCleanup() Out"));
   9640 }
   9641 
   9642 
   9643 void PVPlayerEngine::DoSourceNodeCleanup(void)
   9644 {
   9645     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeCleanup() In"));
   9646 
   9647     if (iSourceNode)
   9648     {
   9649         // Remove reference to the parser node init interface if available
   9650         if (iSourceNodeInitIF)
   9651         {
   9652             iSourceNodeInitIF->removeRef();
   9653             iSourceNodeInitIF = NULL;
   9654             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeInitIF Released"));
   9655         }
   9656 
   9657         // Remove reference to the parser node track sel interface if available
   9658         if (iSourceNodeTrackSelIF)
   9659         {
   9660             iPlayableList.Reset();
   9661             iPreferenceList.Reset();
   9662             iSourceNodeTrackSelIF->removeRef();
   9663             iSourceNodeTrackSelIF = NULL;
   9664             iTrackSelectionHelper = NULL;
   9665             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeTrackSelIF Released"));
   9666         }
   9667 
   9668         // Remove reference to the parser node track level info interface if available
   9669         if (iSourceNodeTrackLevelInfoIF)
   9670         {
   9671             iSourceNodeTrackLevelInfoIF->removeRef();
   9672             iSourceNodeTrackLevelInfoIF = NULL;
   9673             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeTrackLevelInfoIF Released"));
   9674         }
   9675 
   9676         // Remove reference to the parser node position control interface if available
   9677         if (iSourceNodePBCtrlIF)
   9678         {
   9679             iSourceNodePBCtrlIF->removeRef();
   9680             iSourceNodePBCtrlIF = NULL;
   9681             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodePBCtrlIF Released"));
   9682         }
   9683 
   9684         // Remove reference to the parser node direction control interface if available
   9685         if (iSourceNodeDirCtrlIF)
   9686         {
   9687             iSourceNodeDirCtrlIF->removeRef();
   9688             iSourceNodeDirCtrlIF = NULL;
   9689             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeDirCtrlIF Released"));
   9690         }
   9691 
   9692         // Remove reference to the parser node metadata interface if available
   9693         if (iSourceNodeMetadataExtIF)
   9694         {
   9695             RemoveFromMetadataInterfaceList(iSourceNodeMetadataExtIF, iSourceNodeSessionId);
   9696             iSourceNodeMetadataExtIF->removeRef();
   9697             iSourceNodeMetadataExtIF = NULL;
   9698             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeMetadataExtIF Released"));
   9699         }
   9700 
   9701         // Reset the duration value retrieved from source
   9702         iSourceDurationAvailable = false;
   9703         iSourceDurationInMS = 0;
   9704 
   9705         // Remove reference to the parser node cap-config interface if available
   9706         if (iSourceNodeCapConfigIF)
   9707         {
   9708             iSourceNodeCapConfigIF->removeRef();
   9709             iSourceNodeCapConfigIF = NULL;
   9710             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeCapConfigIF Released"));
   9711         }
   9712 
   9713         if (iSourceNodeCPMLicenseIF)
   9714         {
   9715             iSourceNodeCPMLicenseIF->removeRef();
   9716             iSourceNodeCPMLicenseIF = NULL;
   9717         }
   9718 
   9719         // Reset the Presentation Info list
   9720         iSourcePresInfoList.Reset();
   9721 
   9722         PVMFStatus status = PVMFFailure;
   9723         status = iSourceNode->Disconnect(iSourceNodeSessionId);
   9724         if (status == PVMFFailure)
   9725         {
   9726             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeCleanup() Disconnect Failed"));
   9727             OSCL_ASSERT(false);
   9728         }
   9729         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - DisConnect Done"));
   9730 
   9731         status = iSourceNode->ThreadLogoff();
   9732         if (status == PVMFFailure)
   9733         {
   9734             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeCleanup() ThreadLogoff Failed"));
   9735             OSCL_ASSERT(false);
   9736         }
   9737         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - ThreadLogoff Done"));
   9738 
   9739         // search for matching uuid entry in list of instantiated nodes
   9740         PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
   9741         for (; iter != iNodeUuids.end(); ++iter)
   9742             if (iter->iNode == iSourceNode)
   9743                 break;
   9744 
   9745         if (iter != iNodeUuids.end())
   9746         {
   9747             bool release_status = false;
   9748 
   9749             release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, iSourceNode);
   9750 
   9751             if (release_status == false)
   9752             {
   9753                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeCleanup() Factory returned false while releasing the sourcenode"));
   9754                 return;
   9755             }
   9756 
   9757 
   9758             iNodeUuids.erase(iter);
   9759             iSourceNode = NULL;
   9760             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNode Delete Done"));
   9761         }
   9762         else
   9763         {
   9764             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNode not found"));
   9765             return;
   9766         }
   9767     }
   9768 
   9769     // Cleanup the control varibles related to rate & direction changes.
   9770     iPlaybackDirection_New = iPlaybackDirection;
   9771     iOutsideTimebase_New = iOutsideTimebase;
   9772     iPlaybackClockRate_New = iPlaybackClockRate;
   9773     iChangeDirectionNPT.iIndeterminate = true;
   9774     // Reset the flag that tracks pause-due-to-EOS
   9775     iPlaybackPausedDueToEndOfClip = false;
   9776 
   9777     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeCleanup() Out"));
   9778 }
   9779 
   9780 
   9781 PVMFStatus PVPlayerEngine::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
   9782 {
   9783     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() In"));
   9784     OSCL_UNUSED_ARG(aContext);
   9785 
   9786     // Initialize the output parameters
   9787     aNumParamElements = 0;
   9788     aParameters = NULL;
   9789 
   9790     // Count the number of components and parameters in the key
   9791     int compcount = pv_mime_string_compcnt(aIdentifier);
   9792     // Retrieve the first component from the key string
   9793     char* compstr = NULL;
   9794     pv_mime_string_extract_type(0, aIdentifier, compstr);
   9795 
   9796     if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
   9797     {
   9798         // First component should be "x-pvmf" and there must
   9799         // be at least two components to go past x-pvmf
   9800         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Invalid key string"));
   9801         return PVMFErrArgument;
   9802     }
   9803 
   9804     // Retrieve the second component from the key string
   9805     pv_mime_string_extract_type(1, aIdentifier, compstr);
   9806 
   9807     // First check if it is key string for engine ("player")
   9808     if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
   9809     {
   9810         // Key is for player
   9811         if (compcount == 2)
   9812         {
   9813             // Since key is "x-pvmf/player" return all
   9814             // nodes available at this level. Ignore attribute
   9815             // since capability is only allowed
   9816 
   9817             // Allocate memory for the KVP list
   9818             aParameters = (PvmiKvp*)oscl_malloc(PVPLAYERCONFIG_BASE_NUMKEYS * sizeof(PvmiKvp));
   9819             if (aParameters == NULL)
   9820             {
   9821                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
   9822                 return PVMFErrNoMemory;
   9823             }
   9824             oscl_memset(aParameters, 0, PVPLAYERCONFIG_BASE_NUMKEYS*sizeof(PvmiKvp));
   9825             // Allocate memory for the key strings in each KVP
   9826             PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_BASE_NUMKEYS * PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
   9827             if (memblock == NULL)
   9828             {
   9829                 oscl_free(aParameters);
   9830                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
   9831                 return PVMFErrNoMemory;
   9832             }
   9833             oscl_strset(memblock, 0, PVPLAYERCONFIG_BASE_NUMKEYS*PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
   9834             // Assign the key string buffer to each KVP
   9835             int32 j;
   9836             for (j = 0; j < PVPLAYERCONFIG_BASE_NUMKEYS; ++j)
   9837             {
   9838                 aParameters[j].key = memblock + (j * PVPLAYERCONFIG_KEYSTRING_SIZE);
   9839             }
   9840             // Copy the requested info
   9841             for (j = 0; j < PVPLAYERCONFIG_BASE_NUMKEYS; ++j)
   9842             {
   9843                 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/player/"), 14);
   9844                 oscl_strncat(aParameters[j].key, PVPlayerConfigBaseKeys[j].iString, oscl_strlen(PVPlayerConfigBaseKeys[j].iString));
   9845                 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6);
   9846                 switch (PVPlayerConfigBaseKeys[j].iType)
   9847                 {
   9848                     case PVMI_KVPTYPE_AGGREGATE:
   9849                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING));
   9850                         break;
   9851 
   9852                     case PVMI_KVPTYPE_POINTER:
   9853                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING));
   9854                         break;
   9855 
   9856                     case PVMI_KVPTYPE_VALUE:
   9857                     default:
   9858                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING));
   9859                         break;
   9860                 }
   9861                 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9);
   9862                 switch (PVPlayerConfigBaseKeys[j].iValueType)
   9863                 {
   9864                     case PVMI_KVPVALTYPE_RANGE_INT32:
   9865                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
   9866                         break;
   9867 
   9868                     case PVMI_KVPVALTYPE_KSV:
   9869                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
   9870                         break;
   9871 
   9872                     case PVMI_KVPVALTYPE_CHARPTR:
   9873                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
   9874                         break;
   9875 
   9876                     case PVMI_KVPVALTYPE_BOOL:
   9877                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
   9878                         break;
   9879 
   9880                     case PVMI_KVPVALTYPE_UINT32:
   9881                     default:
   9882                         oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
   9883                         break;
   9884                 }
   9885                 aParameters[j].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
   9886             }
   9887 
   9888             aNumParamElements = PVPLAYERCONFIG_BASE_NUMKEYS;
   9889         }
   9890         else
   9891         {
   9892             // Retrieve the third component from the key string
   9893             pv_mime_string_extract_type(2, aIdentifier, compstr);
   9894 
   9895             for (int32 engcomp3ind = 0; engcomp3ind < PVPLAYERCONFIG_BASE_NUMKEYS; ++engcomp3ind)
   9896             {
   9897                 // Go through each engine component string at 3rd level
   9898                 if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigBaseKeys[engcomp3ind].iString)) >= 0)
   9899                 {
   9900                     if (engcomp3ind == PRODUCTINFO)
   9901                     {
   9902                         // "x-pvmf/player/productinfo"
   9903                         if (compcount == 3)
   9904                         {
   9905                             // Return list of product info. Ignore the
   9906                             // attribute since capability is only allowed
   9907 
   9908                             // Allocate memory for the KVP list
   9909                             aParameters = (PvmiKvp*)oscl_malloc(PVPLAYERCONFIG_PRODINFO_NUMKEYS * sizeof(PvmiKvp));
   9910                             if (aParameters == NULL)
   9911                             {
   9912                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
   9913                                 return PVMFErrNoMemory;
   9914                             }
   9915                             oscl_memset(aParameters, 0, PVPLAYERCONFIG_PRODINFO_NUMKEYS*sizeof(PvmiKvp));
   9916                             // Allocate memory for the key strings in each KVP
   9917                             PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_PRODINFO_NUMKEYS * PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
   9918                             if (memblock == NULL)
   9919                             {
   9920                                 oscl_free(aParameters);
   9921                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
   9922                                 return PVMFErrNoMemory;
   9923                             }
   9924                             oscl_strset(memblock, 0, PVPLAYERCONFIG_PRODINFO_NUMKEYS*PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
   9925                             // Assign the key string buffer to each KVP
   9926                             int32 j;
   9927                             for (j = 0; j < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++j)
   9928                             {
   9929                                 aParameters[j].key = memblock + (j * PVPLAYERCONFIG_KEYSTRING_SIZE);
   9930                             }
   9931                             // Copy the requested info
   9932                             for (j = 0; j < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++j)
   9933                             {
   9934                                 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/player/productinfo/"), 26);
   9935                                 oscl_strncat(aParameters[j].key, PVPlayerConfigProdInfoKeys[j].iString, oscl_strlen(PVPlayerConfigProdInfoKeys[j].iString));
   9936                                 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type=value;valtype=char*"), 25);
   9937                                 aParameters[j].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
   9938                             }
   9939 
   9940                             aNumParamElements = PVPLAYERCONFIG_PRODINFO_NUMKEYS;
   9941                         }
   9942                         else if (compcount == 4)
   9943                         {
   9944                             // Retrieve the fourth component from the key string
   9945                             pv_mime_string_extract_type(3, aIdentifier, compstr);
   9946 
   9947                             for (int32 engcomp4ind = 0; engcomp4ind < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++engcomp4ind)
   9948                             {
   9949                                 if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigProdInfoKeys[engcomp4ind].iString)) >= 0)
   9950                                 {
   9951                                     // Determine what is requested
   9952                                     PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
   9953                                     if (reqattr == PVMI_KVPATTR_UNKNOWN)
   9954                                     {
   9955                                         // Default is current setting
   9956                                         reqattr = PVMI_KVPATTR_CUR;
   9957                                     }
   9958 
   9959                                     // Return the requested info
   9960                                     PVMFStatus retval = DoGetPlayerProductInfoParameter(aParameters, aNumParamElements, engcomp4ind, reqattr);
   9961                                     if (retval != PVMFSuccess)
   9962                                     {
   9963                                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Retrieving product info failed"));
   9964                                         return retval;
   9965                                     }
   9966 
   9967                                     // Break out of the for(engcomp4ind) loop
   9968                                     break;
   9969                                 }
   9970                             }
   9971                         }
   9972                         else
   9973                         {
   9974                             // Right now engine doesn't support more than 4 components
   9975                             // so error out
   9976                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Unsupported key"));
   9977                             return PVMFErrArgument;
   9978                         }
   9979                     }
   9980                     else
   9981                     {
   9982                         if (compcount == 3)
   9983                         {
   9984                             // Determine what is requested
   9985                             PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
   9986                             if (reqattr == PVMI_KVPATTR_UNKNOWN)
   9987                             {
   9988                                 reqattr = PVMI_KVPATTR_CUR;
   9989                             }
   9990 
   9991                             // Return the requested info
   9992                             PVMFStatus retval = DoGetPlayerParameter(aParameters, aNumParamElements, engcomp3ind, reqattr);
   9993                             if (retval != PVMFSuccess)
   9994                             {
   9995                                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Retrieving player parameter failed"));
   9996                                 return retval;
   9997                             }
   9998                         }
   9999                         else
   10000                         {
   10001                             // Right now engine doesn't support more than 3 components
   10002                             // for this sub-key string so error out
   10003                             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Unsupported key"));
   10004                             return PVMFErrArgument;
   10005                         }
   10006                     }
   10007 
   10008                     // Breakout of the for(engcomp3ind) loop
   10009                     break;
   10010                 }
   10011             }
   10012         }
   10013     }
   10014     else
   10015     {
   10016         PVMFStatus retval = PVMFFailure;
   10017 
   10018         // Go through each datapath's cap-config IF in the datapath list and check for the string.
   10019         for (uint32 i = 0; i < iDatapathList.size(); i++)
   10020         {
   10021             if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
   10022             {
   10023                 retval = iDatapathList[i].iDecNodeCapConfigIF->getParametersSync(NULL, aIdentifier, aParameters, aNumParamElements, aContext);
   10024                 if (retval == PVMFSuccess)
   10025                 {
   10026                     // Key matched break the loop.
   10027                     break;
   10028                 }
   10029             }
   10030 
   10031             if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
   10032             {
   10033                 retval = iDatapathList[i].iSinkNodeCapConfigIF->getParametersSync(NULL, aIdentifier, aParameters, aNumParamElements, aContext);
   10034                 if (retval == PVMFSuccess)
   10035                 {
   10036                     // Key matched break the loop.
   10037                     break;
   10038                 }
   10039             }
   10040         }
   10041 
   10042         if (retval != PVMFSuccess)
   10043         {
   10044             return retval;
   10045         }
   10046     }
   10047 
   10048     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Out"));
   10049     if (aNumParamElements == 0)
   10050     {
   10051         // If no one could get the parameter, return error
   10052         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Unsupported key"));
   10053         return PVMFFailure;
   10054     }
   10055     else
   10056     {
   10057         return PVMFSuccess;
   10058     }
   10059 }
   10060 
   10061 
   10062 PVMFStatus PVPlayerEngine::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements)
   10063 {
   10064     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() In"));
   10065 
   10066     if (aParameters == NULL || aNumElements < 1)
   10067     {
   10068         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0"));
   10069         return PVMFErrArgument;
   10070     }
   10071 
   10072     // Count the number of components and parameters in the key
   10073     int compcount = pv_mime_string_compcnt(aParameters[0].key);
   10074     // Retrieve the first component from the key string
   10075     char* compstr = NULL;
   10076     pv_mime_string_extract_type(0, aParameters[0].key, compstr);
   10077 
   10078     if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
   10079     {
   10080         // First component should be "x-pvmf" and there must
   10081         // be at least two components to go past x-pvmf
   10082         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() Unsupported key"));
   10083         return PVMFErrArgument;
   10084     }
   10085 
   10086     // Retrieve the second component from the key string
   10087     pv_mime_string_extract_type(1, aParameters[0].key, compstr);
   10088 
   10089     // Assume all the parameters come from the same component so the base components are the same
   10090     // First check if it is key string for engine ("player")
   10091     if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
   10092     {
   10093         // Go through each KVP and release memory for value if allocated from heap
   10094         for (int32 i = 0; i < aNumElements; ++i)
   10095         {
   10096             // Next check if it is a value type that allocated memory
   10097             PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key);
   10098             if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
   10099             {
   10100                 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key);
   10101                 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
   10102                 {
   10103                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() Valtype not specified in key string"));
   10104                     return PVMFErrArgument;
   10105                 }
   10106 
   10107                 if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
   10108                 {
   10109                     oscl_free(aParameters[i].value.pChar_value);
   10110                     aParameters[i].value.pChar_value = NULL;
   10111                 }
   10112                 else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL)
   10113                 {
   10114                     oscl_free(aParameters[i].value.key_specific_value);
   10115                     aParameters[i].value.key_specific_value = NULL;
   10116                 }
   10117                 else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_INT32 && aParameters[i].value.key_specific_value != NULL)
   10118                 {
   10119                     range_int32* ri32 = (range_int32*)aParameters[i].value.key_specific_value;
   10120                     aParameters[i].value.key_specific_value = NULL;
   10121                     oscl_free(ri32);
   10122                 }
   10123                 else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL)
   10124                 {
   10125                     range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value;
   10126                     aParameters[i].value.key_specific_value = NULL;
   10127                     oscl_free(rui32);
   10128                 }
   10129                 // @TODO Add more types if engine starts returning more types
   10130             }
   10131         }
   10132 
   10133         // Player engine allocated its key strings in one chunk so just free the first key string ptr
   10134         oscl_free(aParameters[0].key);
   10135 
   10136         // Free memory for the parameter list
   10137         oscl_free(aParameters);
   10138         aParameters = NULL;
   10139     }
   10140     else
   10141     {
   10142         PVMFStatus retval = PVMFFailure;
   10143 
   10144         // Go through each datapath's cap-config IF in the datapath list and check for the string.
   10145         for (uint32 i = 0; i < iDatapathList.size(); i++)
   10146         {
   10147             if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
   10148             {
   10149                 retval = iDatapathList[i].iDecNodeCapConfigIF->releaseParameters(NULL, aParameters, aNumElements);
   10150                 if (retval == PVMFSuccess)
   10151                 {
   10152                     // Key matched break the loop.
   10153                     break;
   10154                 }
   10155             }
   10156 
   10157             if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
   10158             {
   10159                 retval = iDatapathList[i].iSinkNodeCapConfigIF->releaseParameters(NULL, aParameters, aNumElements);
   10160                 if (retval == PVMFSuccess)
   10161                 {
   10162                     // Key matched break the loop.
   10163                     break;
   10164                 }
   10165             }
   10166         }
   10167 
   10168         if (retval != PVMFSuccess)
   10169         {
   10170             return retval;
   10171         }
   10172     }
   10173 
   10174     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() Out"));
   10175     return PVMFSuccess;
   10176 }
   10177 
   10178 
   10179 PVMFStatus PVPlayerEngine::DoCapConfigSetParameters(PVPlayerEngineCommand& aCmd, bool aSyncCmd)
   10180 {
   10181     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigSetParameters() In"));
   10182 
   10183     PvmiKvp* paramkvp;
   10184     int32 numparam;
   10185     PvmiKvp** retkvp;
   10186     paramkvp = (PvmiKvp*)(aCmd.GetParam(0).pOsclAny_value);
   10187     numparam = aCmd.GetParam(1).int32_value;
   10188     retkvp = (PvmiKvp**)(aCmd.GetParam(2).pOsclAny_value);
   10189 
   10190     if (paramkvp == NULL || retkvp == NULL || numparam < 1)
   10191     {
   10192         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Passed in parameter invalid"));
   10193         return PVMFErrArgument;
   10194     }
   10195 
   10196     // Go through each parameter
   10197     for (int32 paramind = 0; paramind < numparam; ++paramind)
   10198     {
   10199         if (iRollOverState == RollOverStateIdle)
   10200         {
   10201             PVMFStatus ret = VerifyAndSaveKVPValues(&paramkvp[paramind]);
   10202             if (ret != PVMFSuccess)
   10203             {
   10204                 return ret;
   10205             };
   10206         }
   10207         // Count the number of components and parameters in the key
   10208         int compcount = pv_mime_string_compcnt(paramkvp[paramind].key);
   10209         // Retrieve the first component from the key string
   10210         char* compstr = NULL;
   10211         pv_mime_string_extract_type(0, paramkvp[paramind].key, compstr);
   10212 
   10213         if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
   10214         {
   10215             // First component should be "x-pvmf" and there must
   10216             // be at least two components to go past x-pvmf
   10217             *retkvp = &paramkvp[paramind];
   10218             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Unsupported key"));
   10219             return PVMFErrArgument;
   10220         }
   10221 
   10222         // Retrieve the second component from the key string
   10223         pv_mime_string_extract_type(1, paramkvp[paramind].key, compstr);
   10224 
   10225         // First check if it is key string for engine ("player")
   10226         if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
   10227         {
   10228             if (compcount == 3)
   10229             {
   10230                 // Verify and set the passed-in player setting
   10231                 PVMFStatus retval = DoVerifyAndSetPlayerParameter(paramkvp[paramind], true);
   10232                 if (retval != PVMFSuccess)
   10233                 {
   10234                     *retkvp = &paramkvp[paramind];
   10235                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
   10236                     return retval;
   10237                 }
   10238             }
   10239             else if (compcount == 4)
   10240             {
   10241                 // Only product info keys have four components
   10242                 // Verify and set the passed-in product info setting
   10243                 PVMFStatus retval = DoVerifyAndSetPlayerProductInfoParameter(paramkvp[paramind], true);
   10244                 if (retval != PVMFSuccess)
   10245                 {
   10246                     *retkvp = &paramkvp[paramind];
   10247                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
   10248                     return retval;
   10249                 }
   10250             }
   10251             else
   10252             {
   10253                 // Do not support more than 4 components right now
   10254                 *retkvp = &paramkvp[paramind];
   10255                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Unsupported key"));
   10256                 return PVMFErrArgument;
   10257             }
   10258         }
   10259         else
   10260         {
   10261             *retkvp = &paramkvp[paramind];
   10262             bool anysuccess = false;
   10263 
   10264 
   10265             if (iSourceNodeCapConfigIF != NULL)
   10266             {
   10267                 *retkvp = NULL;
   10268                 iSourceNodeCapConfigIF->setParametersSync(NULL, &paramkvp[paramind], 1, *retkvp);
   10269                 if (*retkvp == NULL)
   10270                 {
   10271                     anysuccess = true;
   10272                 }
   10273             }
   10274             // Go through each datapath's cap-config IF in the datapath list and check for the string.
   10275             for (uint32 i = 0; i < iDatapathList.size(); i++)
   10276             {
   10277                 if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
   10278                 {
   10279                     *retkvp = NULL;
   10280                     iDatapathList[i].iDecNodeCapConfigIF->setParametersSync(NULL, &paramkvp[paramind], 1, *retkvp);
   10281                     if (*retkvp == NULL)
   10282                     {
   10283                         anysuccess = true;
   10284                         break;
   10285                     }
   10286                 }
   10287 
   10288                 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
   10289                 {
   10290                     *retkvp = NULL;
   10291                     iDatapathList[i].iSinkNodeCapConfigIF->setParametersSync(NULL, &paramkvp[paramind], 1, *retkvp);
   10292                     if (*retkvp == NULL)
   10293                     {
   10294                         anysuccess = true;
   10295                         break;
   10296                     }
   10297                 }
   10298             }
   10299 
   10300             if (anysuccess == false)
   10301             {
   10302                 // setParametersSync was not accepted by the node(s)
   10303                 *retkvp = &paramkvp[paramind];
   10304                 return PVMFErrArgument;
   10305             }
   10306         }
   10307 
   10308     }
   10309 
   10310     if (!aSyncCmd)
   10311     {
   10312         EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
   10313     }
   10314 
   10315     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigSetParameters() Out"));
   10316     return PVMFSuccess;
   10317 }
   10318 
   10319 
   10320 PVMFStatus PVPlayerEngine::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
   10321 {
   10322     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() In"));
   10323 
   10324     if (aParameters == NULL || aNumElements < 1)
   10325     {
   10326         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Passed in parameter invalid"));
   10327         return PVMFErrArgument;
   10328     }
   10329 
   10330     // Go through each parameter and verify
   10331     for (int32 paramind = 0; paramind < aNumElements; ++paramind)
   10332     {
   10333         // Count the number of components and parameters in the key
   10334         int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
   10335         // Retrieve the first component from the key string
   10336         char* compstr = NULL;
   10337         pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
   10338 
   10339         if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
   10340         {
   10341             // First component should be "x-pvmf" and there must
   10342             // be at least two components to go past x-pvmf
   10343             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Unsupported key"));
   10344             return PVMFErrArgument;
   10345         }
   10346 
   10347         // Retrieve the second component from the key string
   10348         pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
   10349 
   10350         // First check if it is key string for engine ("player")
   10351         if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
   10352         {
   10353             if (compcount == 3)
   10354             {
   10355                 // Verify the passed-in player setting
   10356                 PVMFStatus retval = DoVerifyAndSetPlayerParameter(aParameters[paramind], false);
   10357                 if (retval != PVMFSuccess)
   10358                 {
   10359                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
   10360                     return retval;
   10361                 }
   10362             }
   10363             else if (compcount == 4)
   10364             {
   10365                 // Only product info keys have four components
   10366                 // Verify the passed-in product info setting
   10367                 PVMFStatus retval = DoVerifyAndSetPlayerProductInfoParameter(aParameters[paramind], false);
   10368                 if (retval != PVMFSuccess)
   10369                 {
   10370                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
   10371                     return retval;
   10372                 }
   10373             }
   10374             else
   10375             {
   10376                 // Do not support more than 4 components right now
   10377                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Unsupported key"));
   10378                 return PVMFErrArgument;
   10379             }
   10380         }
   10381         else
   10382         {
   10383             PVMFStatus retval = PVMFFailure;
   10384 
   10385             // Go through each datapath's cap-config IF in the datapath list and check for the string.
   10386             for (uint32 i = 0; i < iDatapathList.size(); i++)
   10387             {
   10388                 if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
   10389                 {
   10390                     retval = iDatapathList[i].iDecNodeCapConfigIF->verifyParametersSync(NULL, &aParameters[paramind], 1);
   10391                     if (retval == PVMFSuccess)
   10392                     {
   10393                         // Key matched break the loop.
   10394                         break;
   10395                     }
   10396                 }
   10397 
   10398                 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
   10399                 {
   10400                     retval = iDatapathList[i].iSinkNodeCapConfigIF->verifyParametersSync(NULL, &aParameters[paramind], 1);
   10401                     if (retval == PVMFSuccess)
   10402                     {
   10403                         // Key matched break the loop.
   10404                         break;
   10405                     }
   10406                 }
   10407             }
   10408 
   10409             if (retval != PVMFSuccess)
   10410             {
   10411                 return retval;
   10412             }
   10413         }
   10414     }
   10415 
   10416     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Out"));
   10417     return PVMFSuccess;
   10418 }
   10419 
   10420 PVMFStatus PVPlayerEngine::DoGetPlayerParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
   10421 {
   10422     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerParameter() In"));
   10423 
   10424     aNumParamElements = 0;
   10425 
   10426     // Allocate memory for the KVP
   10427     aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
   10428     if (aParameters == NULL)
   10429     {
   10430         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for KVP failed"));
   10431         return PVMFErrNoMemory;
   10432     }
   10433     oscl_memset(aParameters, 0, sizeof(PvmiKvp));
   10434     // Allocate memory for the key string in KVP
   10435     PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
   10436     if (memblock == NULL)
   10437     {
   10438         oscl_free(aParameters);
   10439         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for key string failed"));
   10440         return PVMFErrNoMemory;
   10441     }
   10442     oscl_strset(memblock, 0, PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
   10443     // Assign the key string buffer to KVP
   10444     aParameters[0].key = memblock;
   10445 
   10446     // Copy the key string
   10447     oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/player/"), 14);
   10448     oscl_strncat(aParameters[0].key, PVPlayerConfigBaseKeys[aIndex].iString, oscl_strlen(PVPlayerConfigBaseKeys[aIndex].iString));
   10449     oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
   10450     switch (PVPlayerConfigBaseKeys[aIndex].iValueType)
   10451     {
   10452         case PVMI_KVPVALTYPE_RANGE_INT32:
   10453             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
   10454             break;
   10455 
   10456         case PVMI_KVPVALTYPE_KSV:
   10457             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
   10458             break;
   10459 
   10460         case PVMI_KVPVALTYPE_CHARPTR:
   10461             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
   10462             break;
   10463 
   10464         case PVMI_KVPVALTYPE_BOOL:
   10465             oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
   10466             break;
   10467 
   10468         case PVMI_KVPVALTYPE_UINT32:
   10469         default:
   10470             if (reqattr == PVMI_KVPATTR_CAP)
   10471             {
   10472                 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
   10473             }
   10474             else
   10475             {
   10476                 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
   10477             }
   10478             break;
   10479     }
   10480     aParameters[0].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
   10481 
   10482     // Copy the requested info
   10483     switch (aIndex)
   10484     {
   10485         case PBPOS_UNITS: // "pbpops_units"
   10486             if (reqattr == PVMI_KVPATTR_CUR)
   10487             {
   10488                 // Return current value
   10489                 // Allocate memory for the string
   10490                 char* curstr = (char*)oscl_malloc(32 * sizeof(char));
   10491                 if (curstr == NULL)
   10492                 {
   10493                     oscl_free(aParameters[0].key);
   10494                     oscl_free(aParameters);
   10495                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for char* string failed"));
   10496                     return PVMFErrNoMemory;
   10497                 }
   10498                 oscl_strset(curstr, 0, 32);
   10499                 // Copy the appropriate string based on units being used
   10500                 switch (iPBPosStatusUnit)
   10501                 {
   10502                     case PVPPBPOSUNIT_SEC:
   10503                         oscl_strncpy(curstr, _STRLIT_CHAR("PVPPBPOSUNIT_SEC"), 16);
   10504                         aParameters[0].length = 16;
   10505                         break;
   10506 
   10507                     case PVPPBPOSUNIT_MIN:
   10508                         oscl_strncpy(curstr, _STRLIT_CHAR("PVPPBPOSUNIT_MIN"), 16);
   10509                         aParameters[0].length = 16;
   10510                         break;
   10511 
   10512                     case PVPPBPOSUNIT_MILLISEC:
   10513                     default:
   10514                         oscl_strncpy(curstr, _STRLIT_CHAR("PVPPBPOSUNIT_MILLISEC"), 21);
   10515                         aParameters[0].length = 21;
   10516                         break;
   10517                 }
   10518 
   10519                 aParameters[0].value.pChar_value = curstr;
   10520                 aParameters[0].capacity = 32;
   10521             }
   10522             else if (reqattr == PVMI_KVPATTR_DEF)
   10523             {
   10524                 // Return default
   10525                 // Allocate memory for the string
   10526                 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_CONFIG_PBPOSSTATUSUNIT_DEF_STRING);
   10527                 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
   10528                 if (defstr == NULL)
   10529                 {
   10530                     oscl_free(aParameters[0].key);
   10531                     oscl_free(aParameters);
   10532                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for char* string failed"));
   10533                     return PVMFErrNoMemory;
   10534                 }
   10535                 // Copy and set
   10536                 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_CONFIG_PBPOSSTATUSUNIT_DEF_STRING), defstrlen);
   10537                 defstr[defstrlen] = 0;
   10538                 aParameters[0].value.pChar_value = defstr;
   10539                 aParameters[0].capacity = defstrlen + 1;
   10540                 aParameters[0].length = defstrlen;
   10541             }
   10542             else
   10543             {
   10544                 // Return capability
   10545                 // Allocate memory for the string
   10546                 int32 capstrlen = oscl_strlen(PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_CAP_STRING);
   10547                 char* capstr = (char*)oscl_malloc((capstrlen + 1) * sizeof(char));
   10548                 if (capstr == NULL)
   10549                 {
   10550                     oscl_free(aParameters[0].key);
   10551                     oscl_free(aParameters);
   10552                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for char* string failed"));
   10553                     return PVMFErrNoMemory;
   10554                 }
   10555                 // Copy and set
   10556                 oscl_strncpy(capstr, _STRLIT_CHAR(PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_CAP_STRING), capstrlen);
   10557                 capstr[capstrlen] = 0;
   10558                 aParameters[0].value.pChar_value = capstr;
   10559                 aParameters[0].capacity = capstrlen + 1;
   10560                 aParameters[0].length = capstrlen;
   10561             }
   10562             break;
   10563 
   10564         case PBPOS_INTERVAL:    // "pbpos_interval"
   10565             if (reqattr == PVMI_KVPATTR_CUR)
   10566             {
   10567                 // Return current value
   10568                 aParameters[0].value.uint32_value = iPBPosStatusInterval;
   10569             }
   10570             else if (reqattr == PVMI_KVPATTR_DEF)
   10571             {
   10572                 // Return default
   10573                 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_DEF;
   10574             }
   10575             else
   10576             {
   10577                 // Return capability
   10578                 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
   10579                 if (rui32 == NULL)
   10580                 {
   10581                     oscl_free(aParameters[0].key);
   10582                     oscl_free(aParameters);
   10583                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
   10584                     return PVMFErrNoMemory;
   10585                 }
   10586                 rui32->min = PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MIN;
   10587                 rui32->max = PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MAX;
   10588                 aParameters[0].value.key_specific_value = (void*)rui32;
   10589             }
   10590             break;
   10591 
   10592         case ENDTIMECHECK_INTERVAL: // "endtimecheck_interval"
   10593             if (reqattr == PVMI_KVPATTR_CUR)
   10594             {
   10595                 // Return current value
   10596                 aParameters[0].value.uint32_value = iEndTimeCheckInterval;
   10597             }
   10598             else if (reqattr == PVMI_KVPATTR_DEF)
   10599             {
   10600                 // Return default
   10601                 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_DEF;
   10602             }
   10603             else
   10604             {
   10605                 // Return capability
   10606                 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
   10607                 if (rui32 == NULL)
   10608                 {
   10609                     oscl_free(aParameters[0].key);
   10610                     oscl_free(aParameters);
   10611                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
   10612                     return PVMFErrNoMemory;
   10613                 }
   10614                 rui32->min = PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MIN;
   10615                 rui32->max = PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MAX;
   10616                 aParameters[0].value.key_specific_value = (void*)rui32;
   10617             }
   10618             break;
   10619 
   10620         case SEEKTOSYNCPOINT:   // "seektosyncpoint"
   10621             if (reqattr == PVMI_KVPATTR_CUR)
   10622             {
   10623                 // Return current value
   10624                 aParameters[0].value.bool_value = iSeekToSyncPoint;
   10625             }
   10626             else if (reqattr == PVMI_KVPATTR_DEF)
   10627             {
   10628                 // Return default
   10629                 aParameters[0].value.bool_value = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINT_DEF;
   10630             }
   10631             else
   10632             {
   10633                 // Return capability
   10634                 // Bool so no capability
   10635             }
   10636             break;
   10637 
   10638         case SKIPTOREQUESTEDPOSITION:   // "skiptorequestedpos"
   10639             if (reqattr == PVMI_KVPATTR_CUR)
   10640             {
   10641                 // Return current value
   10642                 aParameters[0].value.bool_value = iSkipToRequestedPosition;
   10643             }
   10644             else if (reqattr == PVMI_KVPATTR_DEF)
   10645             {
   10646                 // Return default
   10647                 aParameters[0].value.bool_value = PVPLAYERENGINE_CONFIG_SKIPTOREQUESTEDPOS_DEF;
   10648             }
   10649             else
   10650             {
   10651                 // Return capability
   10652                 // Bool so no capability
   10653             }
   10654             break;
   10655 
   10656         case SYNCPOINTSEEKWINDOW:   // "syncpointseekwindow"
   10657             if (reqattr == PVMI_KVPATTR_CUR)
   10658             {
   10659                 // Return current value
   10660                 aParameters[0].value.uint32_value = iSyncPointSeekWindow;
   10661             }
   10662             else if (reqattr == PVMI_KVPATTR_DEF)
   10663             {
   10664                 // Return default
   10665                 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_DEF;
   10666             }
   10667             else
   10668             {
   10669                 // Return capability
   10670                 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
   10671                 if (rui32 == NULL)
   10672                 {
   10673                     oscl_free(aParameters[0].key);
   10674                     oscl_free(aParameters);
   10675                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
   10676                     return PVMFErrNoMemory;
   10677                 }
   10678                 rui32->min = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_MIN;
   10679                 rui32->max = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_MAX;
   10680                 aParameters[0].value.key_specific_value = (void*)rui32;
   10681             }
   10682             break;
   10683 
   10684         case SYNCMARGIN_VIDEO:  // "syncmargin_video"
   10685         case SYNCMARGIN_AUDIO:  // "syncmargin_audio"
   10686         case SYNCMARGIN_TEXT:   // "syncmargin_text"
   10687         {
   10688             range_int32* ri32 = (range_int32*)oscl_malloc(sizeof(range_int32));
   10689             if (ri32 == NULL)
   10690             {
   10691                 oscl_free(aParameters[0].key);
   10692                 oscl_free(aParameters);
   10693                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range int32 failed"));
   10694                 return PVMFErrNoMemory;
   10695             }
   10696 
   10697             if (reqattr == PVMI_KVPATTR_CUR)
   10698             {
   10699                 // Return current value
   10700                 if (aIndex == SYNCMARGIN_VIDEO)
   10701                 {
   10702                     // Video
   10703                     ri32->min = iSyncMarginVideo.min;
   10704                     ri32->max = iSyncMarginVideo.max;
   10705                 }
   10706                 else if (aIndex == SYNCMARGIN_AUDIO)
   10707                 {
   10708                     // Audio
   10709                     ri32->min = iSyncMarginAudio.min;
   10710                     ri32->max = iSyncMarginAudio.max;
   10711                 }
   10712                 else
   10713                 {
   10714                     // Text
   10715                     ri32->min = iSyncMarginText.min;
   10716                     ri32->max = iSyncMarginText.max;
   10717                 }
   10718                 aParameters[0].value.key_specific_value = (void*)ri32;
   10719             }
   10720             else if (reqattr == PVMI_KVPATTR_DEF)
   10721             {
   10722                 // Return default
   10723                 ri32->min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
   10724                 ri32->max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
   10725                 aParameters[0].value.key_specific_value = (void*)ri32;
   10726             }
   10727             else
   10728             {
   10729                 // Return capability
   10730                 ri32->min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_MIN;
   10731                 ri32->max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_MAX;
   10732                 aParameters[0].value.key_specific_value = (void*)ri32;
   10733             }
   10734         }
   10735         break;
   10736 
   10737         case NODECMD_TIMEOUT:   // "nodecmd_timeout"
   10738             if (reqattr == PVMI_KVPATTR_CUR)
   10739             {
   10740                 // Return current value
   10741                 aParameters[0].value.uint32_value = iNodeCmdTimeout;
   10742             }
   10743             else if (reqattr == PVMI_KVPATTR_DEF)
   10744             {
   10745                 // Return default
   10746                 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_DEF;
   10747             }
   10748             else
   10749             {
   10750                 // Return capability
   10751                 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
   10752                 if (rui32 == NULL)
   10753                 {
   10754                     oscl_free(aParameters[0].key);
   10755                     oscl_free(aParameters);
   10756                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
   10757                     return PVMFErrNoMemory;
   10758                 }
   10759                 rui32->min = PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MIN;
   10760                 rui32->max = PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MAX;
   10761                 aParameters[0].value.key_specific_value = (void*)rui32;
   10762             }
   10763             break;
   10764 
   10765         case NODEDATAQUEIUING_TIMEOUT:  // "nodedataqueuing_timeout"
   10766             if (reqattr == PVMI_KVPATTR_CUR)
   10767             {
   10768                 // Return current value
   10769                 aParameters[0].value.uint32_value = iNodeDataQueuingTimeout;
   10770             }
   10771             else if (reqattr == PVMI_KVPATTR_DEF)
   10772             {
   10773                 // Return default
   10774                 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_DEF;
   10775             }
   10776             else
   10777             {
   10778                 // Return capability
   10779                 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
   10780                 if (rui32 == NULL)
   10781                 {
   10782                     oscl_free(aParameters[0].key);
   10783                     oscl_free(aParameters);
   10784                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32"));
   10785                     return PVMFErrNoMemory;
   10786                 }
   10787                 rui32->min = PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MIN;
   10788                 rui32->max = PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MAX;
   10789                 aParameters[0].value.key_specific_value = (void*)rui32;
   10790             }
   10791             break;
   10792 
   10793         case PBPOS_ENABLE:  // "pbpos_enable"
   10794             if (reqattr == PVMI_KVPATTR_CUR)
   10795             {
   10796                 // Return current value
   10797                 aParameters[0].value.bool_value = iPBPosEnable;
   10798             }
   10799             else if (reqattr == PVMI_KVPATTR_DEF)
   10800             {
   10801                 // Return default
   10802                 aParameters[0].value.bool_value = true;
   10803             }
   10804             else
   10805             {
   10806                 // Return capability
   10807                 // Bool so no capability
   10808             }
   10809             break;
   10810         default:
   10811             // Invalid index
   10812             oscl_free(aParameters[0].key);
   10813             oscl_free(aParameters);
   10814             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Invalid index to player parameter"));
   10815             return PVMFErrArgument;
   10816     }
   10817 
   10818     aNumParamElements = 1;
   10819 
   10820     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerParameter() Out"));
   10821     return PVMFSuccess;
   10822 }
   10823 
   10824 
   10825 PVMFStatus PVPlayerEngine::DoGetPlayerProductInfoParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
   10826 {
   10827     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() In"));
   10828 
   10829     aNumParamElements = 0;
   10830 
   10831     // Allocate memory for the KVP
   10832     aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
   10833     if (aParameters == NULL)
   10834     {
   10835         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for KVP failed"));
   10836         return PVMFErrNoMemory;
   10837     }
   10838     oscl_memset(aParameters, 0, sizeof(PvmiKvp));
   10839     // Allocate memory for the key string in KVP
   10840     PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
   10841     if (memblock == NULL)
   10842     {
   10843         oscl_free(aParameters);
   10844         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for key string"));
   10845         return PVMFErrNoMemory;
   10846     }
   10847     oscl_strset(memblock, 0, PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
   10848     // Assign the key string buffer to KVP
   10849     aParameters[0].key = memblock;
   10850 
   10851     // Copy the key string
   10852     oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/player/productinfo/"), 26);
   10853     oscl_strncat(aParameters[0].key, PVPlayerConfigProdInfoKeys[aIndex].iString, oscl_strlen(PVPlayerConfigProdInfoKeys[aIndex].iString));
   10854     oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype=char*"), 25);
   10855     aParameters[0].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
   10856 
   10857     // Copy the requested info
   10858     switch (aIndex)
   10859     {
   10860         case PRODUCTNAME: // "productname"
   10861             if (reqattr == PVMI_KVPATTR_CUR)
   10862             {
   10863                 // Return current value
   10864                 // Allocate memory for the string
   10865                 char* curstr = (char*)oscl_malloc(iProdInfoProdName.get_size() + 1);
   10866                 if (curstr == NULL)
   10867                 {
   10868                     oscl_free(aParameters[0].key);
   10869                     oscl_free(aParameters);
   10870                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   10871                     return PVMFErrNoMemory;
   10872                 }
   10873                 oscl_strset(curstr, 0, iProdInfoProdName.get_size() + 1);
   10874                 // Copy and set
   10875                 oscl_strncpy(curstr, iProdInfoProdName.get_cstr(), iProdInfoProdName.get_size());
   10876                 aParameters[0].value.pChar_value = curstr;
   10877                 aParameters[0].length = iProdInfoProdName.get_size();
   10878                 aParameters[0].capacity = iProdInfoProdName.get_size() + 1;
   10879             }
   10880             else if (reqattr == PVMI_KVPATTR_DEF)
   10881             {
   10882                 // Return default
   10883                 // Allocate memory for the string
   10884                 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_PRODNAME_STRING);
   10885                 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
   10886                 if (defstr == NULL)
   10887                 {
   10888                     oscl_free(aParameters[0].key);
   10889                     oscl_free(aParameters);
   10890                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   10891                     return PVMFErrNoMemory;
   10892                 }
   10893                 // Copy and set
   10894                 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PRODNAME_STRING), defstrlen);
   10895                 defstr[defstrlen] = 0;
   10896                 aParameters[0].value.pChar_value = defstr;
   10897                 aParameters[0].capacity = defstrlen + 1;
   10898                 aParameters[0].length = defstrlen;
   10899             }
   10900             else
   10901             {
   10902                 // Return capability
   10903                 // Empty string
   10904                 aParameters[0].value.pChar_value = NULL;
   10905                 aParameters[0].capacity = 0;
   10906                 aParameters[0].length = 0;
   10907             }
   10908             break;
   10909 
   10910         case PARTNUMBER: // "partnumber"
   10911             if (reqattr == PVMI_KVPATTR_CUR)
   10912             {
   10913                 // Return current value
   10914                 // Allocate memory for the string
   10915                 char* curstr = (char*)oscl_malloc(iProdInfoPartNum.get_size() + 1);
   10916                 if (curstr == NULL)
   10917                 {
   10918                     oscl_free(aParameters[0].key);
   10919                     oscl_free(aParameters);
   10920                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   10921                     return PVMFErrNoMemory;
   10922                 }
   10923                 oscl_strset(curstr, 0, iProdInfoPartNum.get_size() + 1);
   10924                 // Copy and set
   10925                 oscl_strncpy(curstr, iProdInfoPartNum.get_cstr(), iProdInfoPartNum.get_size());
   10926                 aParameters[0].value.pChar_value = curstr;
   10927                 aParameters[0].length = iProdInfoPartNum.get_size();
   10928                 aParameters[0].capacity = iProdInfoPartNum.get_size() + 1;
   10929             }
   10930             else if (reqattr == PVMI_KVPATTR_DEF)
   10931             {
   10932                 // Return default
   10933                 // Allocate memory for the string
   10934                 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_PARTNUM_STRING);
   10935                 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
   10936                 if (defstr == NULL)
   10937                 {
   10938                     oscl_free(aParameters[0].key);
   10939                     oscl_free(aParameters);
   10940                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   10941                     return PVMFErrNoMemory;
   10942                 }
   10943                 // Copy and set
   10944                 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PARTNUM_STRING), defstrlen);
   10945                 defstr[defstrlen] = 0;
   10946                 aParameters[0].value.pChar_value = defstr;
   10947                 aParameters[0].capacity = defstrlen + 1;
   10948                 aParameters[0].length = defstrlen;
   10949             }
   10950             else
   10951             {
   10952                 // Return capability
   10953                 // Empty string
   10954                 aParameters[0].value.pChar_value = NULL;
   10955                 aParameters[0].capacity = 0;
   10956                 aParameters[0].length = 0;
   10957             }
   10958             break;
   10959 
   10960         case HARDWAREPLATFORM: // "hardwareplatform"
   10961             if (reqattr == PVMI_KVPATTR_CUR)
   10962             {
   10963                 // Return current value
   10964                 // Allocate memory for the string
   10965                 char* curstr = (char*)oscl_malloc(iProdInfoHWPlatform.get_size() + 1);
   10966                 if (curstr == NULL)
   10967                 {
   10968                     oscl_free(aParameters[0].key);
   10969                     oscl_free(aParameters);
   10970                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   10971                     return PVMFErrNoMemory;
   10972                 }
   10973                 oscl_strset(curstr, 0, iProdInfoHWPlatform.get_size() + 1);
   10974                 // Copy and set
   10975                 oscl_strncpy(curstr, iProdInfoHWPlatform.get_cstr(), iProdInfoHWPlatform.get_size());
   10976                 aParameters[0].value.pChar_value = curstr;
   10977                 aParameters[0].length = iProdInfoHWPlatform.get_size();
   10978                 aParameters[0].capacity = iProdInfoHWPlatform.get_size() + 1;
   10979             }
   10980             else if (reqattr == PVMI_KVPATTR_DEF)
   10981             {
   10982                 // Return default
   10983                 // Allocate memory for the string
   10984                 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_HWPLATFORM_STRING);
   10985                 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
   10986                 if (defstr == NULL)
   10987                 {
   10988                     oscl_free(aParameters[0].key);
   10989                     oscl_free(aParameters);
   10990                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   10991                     return PVMFErrNoMemory;
   10992                 }
   10993                 // Copy and set
   10994                 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_HWPLATFORM_STRING), defstrlen);
   10995                 defstr[defstrlen] = 0;
   10996                 aParameters[0].value.pChar_value = defstr;
   10997                 aParameters[0].capacity = defstrlen + 1;
   10998                 aParameters[0].length = defstrlen;
   10999             }
   11000             else
   11001             {
   11002                 // Return capability
   11003                 // Empty string
   11004                 aParameters[0].value.pChar_value = NULL;
   11005                 aParameters[0].capacity = 0;
   11006                 aParameters[0].length = 0;
   11007             }
   11008             break;
   11009 
   11010         case SOFTWAREPLATFORM: // "softwareplatform"
   11011             if (reqattr == PVMI_KVPATTR_CUR)
   11012             {
   11013                 // Return current value
   11014                 // Allocate memory for the string
   11015                 char* curstr = (char*)oscl_malloc(iProdInfoSWPlatform.get_size() + 1);
   11016                 if (curstr == NULL)
   11017                 {
   11018                     oscl_free(aParameters[0].key);
   11019                     oscl_free(aParameters);
   11020                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   11021                     return PVMFErrNoMemory;
   11022                 }
   11023                 oscl_strset(curstr, 0, iProdInfoSWPlatform.get_size() + 1);
   11024                 // Copy and set
   11025                 oscl_strncpy(curstr, iProdInfoSWPlatform.get_cstr(), iProdInfoSWPlatform.get_size());
   11026                 aParameters[0].value.pChar_value = curstr;
   11027                 aParameters[0].length = iProdInfoSWPlatform.get_size();
   11028                 aParameters[0].capacity = iProdInfoSWPlatform.get_size() + 1;
   11029             }
   11030             else if (reqattr == PVMI_KVPATTR_DEF)
   11031             {
   11032                 // Return default
   11033                 // Allocate memory for the string
   11034                 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_SWPLATFORM_STRING);
   11035                 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
   11036                 if (defstr == NULL)
   11037                 {
   11038                     oscl_free(aParameters[0].key);
   11039                     oscl_free(aParameters);
   11040                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   11041                     return PVMFErrNoMemory;
   11042                 }
   11043                 // Copy and set
   11044                 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_SWPLATFORM_STRING), defstrlen);
   11045                 defstr[defstrlen] = 0;
   11046                 aParameters[0].value.pChar_value = defstr;
   11047                 aParameters[0].capacity = defstrlen + 1;
   11048                 aParameters[0].length = defstrlen;
   11049             }
   11050             else
   11051             {
   11052                 // Return capability
   11053                 // Empty string
   11054                 aParameters[0].value.pChar_value = NULL;
   11055                 aParameters[0].capacity = 0;
   11056                 aParameters[0].length = 0;
   11057             }
   11058             break;
   11059 
   11060         case DEVICE: // "device"
   11061             if (reqattr == PVMI_KVPATTR_CUR)
   11062             {
   11063                 // Return current value
   11064                 // Allocate memory for the string
   11065                 char* curstr = (char*)oscl_malloc(iProdInfoDevice.get_size() + 1);
   11066                 if (curstr == NULL)
   11067                 {
   11068                     oscl_free(aParameters[0].key);
   11069                     oscl_free(aParameters);
   11070                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   11071                     return PVMFErrNoMemory;
   11072                 }
   11073                 oscl_strset(curstr, 0, iProdInfoDevice.get_size() + 1);
   11074                 // Copy and set
   11075                 oscl_strncpy(curstr, iProdInfoPartNum.get_cstr(), iProdInfoDevice.get_size());
   11076                 aParameters[0].value.pChar_value = curstr;
   11077                 aParameters[0].length = iProdInfoDevice.get_size();
   11078                 aParameters[0].capacity = iProdInfoDevice.get_size() + 1;
   11079             }
   11080             else if (reqattr == PVMI_KVPATTR_DEF)
   11081             {
   11082                 // Return default
   11083                 // Allocate memory for the string
   11084                 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_DEVICE_STRING);
   11085                 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
   11086                 if (defstr == NULL)
   11087                 {
   11088                     oscl_free(aParameters[0].key);
   11089                     oscl_free(aParameters);
   11090                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
   11091                     return PVMFErrNoMemory;
   11092                 }
   11093                 // Copy and set
   11094                 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_DEVICE_STRING), defstrlen);
   11095                 defstr[defstrlen] = 0;
   11096                 aParameters[0].value.pChar_value = defstr;
   11097                 aParameters[0].capacity = defstrlen + 1;
   11098                 aParameters[0].length = defstrlen;
   11099             }
   11100             else
   11101             {
   11102                 // Return capability
   11103                 // Empty string
   11104                 aParameters[0].value.pChar_value = NULL;
   11105                 aParameters[0].capacity = 0;
   11106                 aParameters[0].length = 0;
   11107             }
   11108             break;
   11109 
   11110         default:
   11111             // Invalid index
   11112             oscl_free(aParameters[0].key);
   11113             oscl_free(aParameters);
   11114             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Invalid index for product info"));
   11115             return PVMFErrArgument;
   11116     }
   11117 
   11118     aNumParamElements = 1;
   11119 
   11120     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Out"));
   11121     return PVMFSuccess;
   11122 }
   11123 
   11124 
   11125 PVMFStatus PVPlayerEngine::DoVerifyAndSetPlayerParameter(PvmiKvp& aParameter, bool aSetParam)
   11126 {
   11127     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() In"));
   11128 
   11129     // Determine the valtype
   11130     PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
   11131     if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
   11132     {
   11133         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Valtype in key string unknown"));
   11134         return PVMFErrArgument;
   11135     }
   11136     // Retrieve the third component from the key string
   11137     char* compstr = NULL;
   11138     pv_mime_string_extract_type(2, aParameter.key, compstr);
   11139 
   11140     int32 engcomp3ind = 0;
   11141     for (engcomp3ind = 0; engcomp3ind < PVPLAYERCONFIG_BASE_NUMKEYS; ++engcomp3ind)
   11142     {
   11143         // Go through each engine component string at 3rd level
   11144         if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigBaseKeys[engcomp3ind].iString)) >= 0)
   11145         {
   11146             // Break out of the for loop
   11147             break;
   11148         }
   11149     }
   11150 
   11151     if (engcomp3ind >= PVPLAYERCONFIG_BASE_NUMKEYS || engcomp3ind == PRODUCTINFO)
   11152     {
   11153         // Match couldn't be found or non-leaf node ("productinfo") specified
   11154         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Unsupported key or non-leaf node"));
   11155         return PVMFErrArgument;
   11156     }
   11157 
   11158     // Verify the valtype
   11159     if (keyvaltype != PVPlayerConfigBaseKeys[engcomp3ind].iValueType)
   11160     {
   11161         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Valtype does not match for key"));
   11162         return PVMFErrArgument;
   11163     }
   11164 
   11165     switch (engcomp3ind)
   11166     {
   11167         case PBPOS_UNITS: // "pbpos_units"
   11168         {
   11169             // Validate
   11170             if (aParameter.value.pChar_value == NULL)
   11171             {
   11172                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() char* string for pbpos_units is NULL"));
   11173                 return PVMFErrArgument;
   11174             }
   11175 
   11176             // Check the specified unit
   11177             // Use sample number as the invalid default since it is not allowed
   11178             PVPPlaybackPositionUnit newposunit = PVPPBPOSUNIT_UNKNOWN;
   11179             if (oscl_strncmp(aParameter.value.pChar_value, _STRLIT_CHAR("PVPPBPOSUNIT_SEC"), 16) == 0)
   11180             {
   11181                 newposunit = PVPPBPOSUNIT_SEC;
   11182             }
   11183             else if (oscl_strncmp(aParameter.value.pChar_value, _STRLIT_CHAR("PVPPBPOSUNIT_MIN"), 16) == 0)
   11184             {
   11185                 newposunit = PVPPBPOSUNIT_MIN;
   11186             }
   11187             else if (oscl_strncmp(aParameter.value.pChar_value, _STRLIT_CHAR("PVPPBPOSUNIT_MILLISEC"), 21) == 0)
   11188             {
   11189                 newposunit = PVPPBPOSUNIT_MILLISEC;
   11190             }
   11191 
   11192             if (newposunit == PVPPBPOSUNIT_UNKNOWN)
   11193             {
   11194                 // Couldn't determine the new units
   11195                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid units for pbpos_units"));
   11196                 return PVMFErrArgument;
   11197             }
   11198             // Change the config if to set
   11199             if (aSetParam)
   11200             {
   11201                 iPBPosStatusUnit = newposunit;
   11202             }
   11203         }
   11204         break;
   11205 
   11206         case PBPOS_INTERVAL: // "pbpos_interval"
   11207             // Check if within range
   11208             if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MIN ||
   11209                     aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MAX)
   11210             {
   11211                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for pbpos_interval"));
   11212                 return PVMFErrArgument;
   11213             }
   11214             // Change the config if to set
   11215             if (aSetParam)
   11216             {
   11217                 iPBPosStatusInterval = aParameter.value.uint32_value;
   11218             }
   11219             break;
   11220 
   11221         case ENDTIMECHECK_INTERVAL: // "endtimecheck_interval"
   11222             // Check if within range
   11223             if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MIN ||
   11224                     aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MAX)
   11225             {
   11226                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for endtimecheck_interval"));
   11227                 return PVMFErrArgument;
   11228             }
   11229             // Change the config if to set
   11230             if (aSetParam)
   11231             {
   11232                 iEndTimeCheckInterval = aParameter.value.uint32_value;
   11233             }
   11234             break;
   11235 
   11236         case SEEKTOSYNCPOINT: // "seektosyncpoint"
   11237             // Nothing to validate since it is boolean
   11238             // Change the config if to set
   11239             if (aSetParam)
   11240             {
   11241                 iSeekToSyncPoint = aParameter.value.bool_value;
   11242             }
   11243             break;
   11244 
   11245         case SKIPTOREQUESTEDPOSITION: // "skiptorequestedpos"
   11246             // Nothing to validate since it is boolean
   11247             // Change the config if to set
   11248             if (aSetParam)
   11249             {
   11250                 iSkipToRequestedPosition = aParameter.value.bool_value;
   11251             }
   11252             break;
   11253 
   11254         case SYNCPOINTSEEKWINDOW: // "syncpointseekwindow"
   11255             // Check if within range
   11256             if (aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_MAX)
   11257             {
   11258                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for syncpointseekwindow"));
   11259                 return PVMFErrArgument;
   11260             }
   11261             // Change the config if to set
   11262             if (aSetParam)
   11263             {
   11264                 iSyncPointSeekWindow = aParameter.value.uint32_value;
   11265             }
   11266             break;
   11267 
   11268         case SYNCMARGIN_VIDEO: // "syncmargin_video"
   11269         case SYNCMARGIN_AUDIO: // "syncmargin_audio"
   11270         case SYNCMARGIN_TEXT: // "syncmargin_text"
   11271         {
   11272             range_int32* ri32 = (range_int32*)aParameter.value.key_specific_value;
   11273             if (ri32 == NULL)
   11274             {
   11275                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() ksv for syncmargin is NULL"));
   11276                 return PVMFErrArgument;
   11277             }
   11278 
   11279             // Check if within range
   11280             if (ri32->min < PVPLAYERENGINE_CONFIG_SYNCMARGIN_MIN ||
   11281                     ri32->min > PVPLAYERENGINE_CONFIG_SYNCMARGIN_MAX ||
   11282                     ri32->max < PVPLAYERENGINE_CONFIG_SYNCMARGIN_MIN ||
   11283                     ri32->max > PVPLAYERENGINE_CONFIG_SYNCMARGIN_MAX)
   11284             {
   11285                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid range for syncmargin"));
   11286                 return PVMFErrArgument;
   11287             }
   11288 
   11289             // Change the config if to set
   11290             if (aSetParam)
   11291             {
   11292                 return DoSetConfigSyncMargin(ri32->min, ri32->max, engcomp3ind - 7);
   11293             }
   11294         }
   11295         break;
   11296 
   11297         case NODECMD_TIMEOUT: // "nodecmd_timeout"
   11298             // Check if within range
   11299             if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MIN ||
   11300                     aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MAX)
   11301             {
   11302                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for ndoecmd_timeout"));
   11303                 return PVMFErrArgument;
   11304             }
   11305             // Change the config if to set
   11306             if (aSetParam)
   11307             {
   11308                 iNodeCmdTimeout = aParameter.value.uint32_value;
   11309             }
   11310             break;
   11311 
   11312         case NODEDATAQUEIUING_TIMEOUT: // "nodedataqueuing_timeout"
   11313             // Check if within range
   11314             if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MIN ||
   11315                     aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MAX)
   11316             {
   11317                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for nodedataqueuing_timeout"));
   11318                 return PVMFErrArgument;
   11319             }
   11320             // Change the config if to set
   11321             if (aSetParam)
   11322             {
   11323                 iNodeDataQueuingTimeout = aParameter.value.uint32_value;
   11324             }
   11325             break;
   11326 
   11327         case PBPOS_ENABLE: // "pbpos_enable"
   11328             // Nothing to validate since it is boolean
   11329             // Change the config if to set
   11330             if (aSetParam)
   11331             {
   11332                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() pbpos_enable set to %d", iPBPosEnable));
   11333                 bool prevPBPosEnable = iPBPosEnable;
   11334                 iPBPosEnable = aParameter.value.bool_value;
   11335                 if (prevPBPosEnable && !(aParameter.value.bool_value))
   11336                 {
   11337                     // Stop playback position reporting
   11338                     StopPlaybackStatusTimer();
   11339                 }
   11340                 else if (!prevPBPosEnable && (aParameter.value.bool_value))
   11341                 {
   11342                     // Start playback position reporting only when playback clock is running
   11343                     if (iPlaybackClock.GetState() == PVMFMediaClock::RUNNING)
   11344                     {
   11345                         StartPlaybackStatusTimer();
   11346                     }
   11347                 }
   11348 
   11349             }
   11350             break;
   11351 
   11352         default:
   11353             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid index for player parameter"));
   11354             return PVMFErrArgument;
   11355     }
   11356 
   11357     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Out"));
   11358     return PVMFSuccess;
   11359 }
   11360 
   11361 
   11362 PVMFStatus PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter(PvmiKvp& aParameter, bool aSetParam)
   11363 {
   11364     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() In"));
   11365 
   11366     // Determine the valtype
   11367     PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
   11368     if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
   11369     {
   11370         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Valtype unknown"));
   11371         return PVMFErrArgument;
   11372     }
   11373     // Retrieve the 4th component from the key string
   11374     char* compstr = NULL;
   11375     pv_mime_string_extract_type(3, aParameter.key, compstr);
   11376 
   11377     int32 engcomp4ind = 0;
   11378     for (engcomp4ind = 0; engcomp4ind < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++engcomp4ind)
   11379     {
   11380         // Go through each engine component string at 4th level
   11381         if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigProdInfoKeys[engcomp4ind].iString)) >= 0)
   11382         {
   11383             // Break out of the for loop
   11384             break;
   11385         }
   11386     }
   11387 
   11388     if (engcomp4ind >= PVPLAYERCONFIG_PRODINFO_NUMKEYS)
   11389     {
   11390         // Match couldn't be found
   11391         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Unsupported key"));
   11392         return PVMFErrArgument;
   11393     }
   11394 
   11395     // Verify the valtype
   11396     if (keyvaltype != PVPlayerConfigProdInfoKeys[engcomp4ind].iValueType)
   11397     {
   11398         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Valtype does not match for key"));
   11399         return PVMFErrArgument;
   11400     }
   11401 
   11402     switch (engcomp4ind)
   11403     {
   11404         case PRODUCTNAME: // "productname"
   11405             // Check if within range
   11406             if (aParameter.value.pChar_value == NULL)
   11407             {
   11408                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
   11409                 return PVMFErrArgument;
   11410             }
   11411             // Change the config if to set
   11412             if (aSetParam)
   11413             {
   11414                 iProdInfoProdName = aParameter.value.pChar_value;
   11415             }
   11416             break;
   11417 
   11418         case PARTNUMBER: // "partnumber"
   11419             // Check if within range
   11420             if (aParameter.value.pChar_value == NULL)
   11421             {
   11422                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
   11423                 return PVMFErrArgument;
   11424             }
   11425             // Change the config if to set
   11426             if (aSetParam)
   11427             {
   11428                 iProdInfoPartNum = aParameter.value.pChar_value;
   11429             }
   11430             break;
   11431 
   11432         case HARDWAREPLATFORM: // "hardwareplatform"
   11433             // Check if within range
   11434             if (aParameter.value.pChar_value == NULL)
   11435             {
   11436                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
   11437                 return PVMFErrArgument;
   11438             }
   11439             // Change the config if to set
   11440             if (aSetParam)
   11441             {
   11442                 iProdInfoHWPlatform = aParameter.value.pChar_value;
   11443             }
   11444             break;
   11445 
   11446         case SOFTWAREPLATFORM: // "softwareplatform"
   11447             // Check if within range
   11448             if (aParameter.value.pChar_value == NULL)
   11449             {
   11450                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
   11451                 return PVMFErrArgument;
   11452             }
   11453             // Change the config if to set
   11454             if (aSetParam)
   11455             {
   11456                 iProdInfoSWPlatform = aParameter.value.pChar_value;
   11457             }
   11458             break;
   11459 
   11460         case DEVICE: // "device"
   11461             // Check if within range
   11462             if (aParameter.value.pChar_value == NULL)
   11463             {
   11464                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
   11465                 return PVMFErrArgument;
   11466             }
   11467             // Change the config if to set
   11468             if (aSetParam)
   11469             {
   11470                 iProdInfoDevice = aParameter.value.pChar_value;
   11471             }
   11472             break;
   11473 
   11474         default:
   11475             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Invalid index for product info"));
   11476             return PVMFErrArgument;
   11477     }
   11478 
   11479     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Out"));
   11480     return PVMFSuccess;
   11481 }
   11482 
   11483 
   11484 PVMFStatus PVPlayerEngine::DoSetConfigSyncMargin(int32 aEarlyMargin, int32 aLateMargin, int32 aMediaType)
   11485 {
   11486     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetConfigSyncMargin() In"));
   11487 
   11488     if (aMediaType == 0)
   11489     {
   11490         // Video
   11491         iSyncMarginVideo.min = aEarlyMargin;
   11492         iSyncMarginVideo.max = aLateMargin;
   11493 
   11494         // Find the video datapath in the list
   11495         int32 vdpind = -1;
   11496         if (FindDatapathForTrackUsingMimeString(true, false, false, vdpind) == true)
   11497         {
   11498             PVPlayerEngineDatapath* pvpedp = &(iDatapathList[vdpind]);
   11499             if (pvpedp->iDatapath)
   11500             {
   11501                 if (pvpedp->iSinkNodeSyncCtrlIF)
   11502                 {
   11503                     pvpedp->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginVideo.min), iSyncMarginVideo.max);
   11504                 }
   11505             }
   11506         }
   11507     }
   11508     else if (aMediaType == 1)
   11509     {
   11510         // Audio
   11511         iSyncMarginAudio.min = aEarlyMargin;
   11512         iSyncMarginAudio.max = aLateMargin;
   11513 
   11514         // Find the audio datapath in the list
   11515         int32 adpind = -1;
   11516         if (FindDatapathForTrackUsingMimeString(false, true, false, adpind) == true)
   11517         {
   11518             PVPlayerEngineDatapath* pvpedp = &(iDatapathList[adpind]);
   11519             if (pvpedp->iDatapath)
   11520             {
   11521                 if (pvpedp->iSinkNodeSyncCtrlIF)
   11522                 {
   11523                     pvpedp->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginAudio.min), iSyncMarginAudio.max);
   11524                 }
   11525             }
   11526         }
   11527     }
   11528     else if (aMediaType == 2)
   11529     {
   11530         // Text
   11531         iSyncMarginText.min = aEarlyMargin;
   11532         iSyncMarginText.max = aLateMargin;
   11533 
   11534         // Find the text datapath in the list
   11535         int32 tdpind = -1;
   11536         if (FindDatapathForTrackUsingMimeString(false, false, true, tdpind) == true)
   11537         {
   11538             PVPlayerEngineDatapath* pvpedp = &(iDatapathList[tdpind]);
   11539             if (pvpedp->iDatapath)
   11540             {
   11541                 if (pvpedp->iSinkNodeSyncCtrlIF)
   11542                 {
   11543                     pvpedp->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginText.min), iSyncMarginText.max);
   11544                 }
   11545             }
   11546         }
   11547     }
   11548     else
   11549     {
   11550         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetConfigSyncMargin() Invalid media type index"));
   11551         return PVMFErrArgument;
   11552     }
   11553 
   11554     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetConfigSyncMargin() Out"));
   11555     return PVMFSuccess;
   11556 }
   11557 
   11558 
   11559 PVPlayerEngineContext* PVPlayerEngine::AllocateEngineContext(PVPlayerEngineDatapath* aEngineDatapath, PVMFNodeInterface* aNode, PVPlayerDatapath* aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext, int32 aCmdType)
   11560 {
   11561     // Allocate memory for the context from the fixed size memory pool
   11562     PVPlayerEngineContext* context = NULL;
   11563     int32 leavecode = 0;
   11564     OSCL_TRY(leavecode, context = (PVPlayerEngineContext*)(iCurrentContextListMemPool.allocate(sizeof(PVPlayerEngineContext))));
   11565     OSCL_FIRST_CATCH_ANY(leavecode,
   11566                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::AllocateEngineContext() allocate on iCurrentContextListMemPool did a leave!"));
   11567                          OSCL_ASSERT(false));
   11568 
   11569     OSCL_ASSERT(context);
   11570 
   11571     // Set the context info
   11572     context->iEngineDatapath = aEngineDatapath;
   11573     context->iNode = aNode;
   11574     context->iDatapath = aDatapath;
   11575     context->iCmdId = aCmdId;
   11576     context->iCmdContext = aCmdContext;
   11577     context->iCmdType = aCmdType;
   11578 
   11579     // Save the context in the list
   11580     leavecode = 0;
   11581     OSCL_TRY(leavecode, iCurrentContextList.push_back(context));
   11582     OSCL_FIRST_CATCH_ANY(leavecode,
   11583                          PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::AllocateEngineContext() Push back on the context list did a leave!"));
   11584                          iCurrentContextListMemPool.deallocate((OsclAny*)context);
   11585                          OSCL_ASSERT(false);
   11586                          return NULL;);
   11587 
   11588     return context;
   11589 }
   11590 
   11591 
   11592 void PVPlayerEngine::FreeEngineContext(PVPlayerEngineContext* aContext)
   11593 {
   11594     OSCL_ASSERT(aContext);
   11595 
   11596     // Remove the context from the list
   11597     uint32 i = 0;
   11598     bool foundcontext = false;
   11599     for (i = 0; i < iCurrentContextList.size(); ++i)
   11600     {
   11601         if (iCurrentContextList[i] == aContext)
   11602         {
   11603             foundcontext = true;
   11604             break;
   11605         }
   11606     }
   11607 
   11608     if (foundcontext)
   11609     {
   11610         iCurrentContextList.erase(iCurrentContextList.begin() + i);
   11611         // Free the memory used by context in the memory pool
   11612         iCurrentContextListMemPool.deallocate((OsclAny*)aContext);
   11613     }
   11614     else
   11615     {
   11616         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::FreeEngineContext() Context not on current list (0x%x). CmdType %d", aContext, aContext->iCmdType));
   11617         OSCL_ASSERT(false);
   11618         // Don't return to memory pool since it could add multiple entries
   11619         // of same address in free list
   11620     }
   11621 }
   11622 
   11623 
   11624 void PVPlayerEngine::HandleSourceNodeQueryInitIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   11625 {
   11626     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   11627                     (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() Tick=%d", OsclTickCount::TickCount()));
   11628 
   11629     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() In"));
   11630 
   11631     PVMFStatus cmdstatus;
   11632     bool rescheduleAO = false;
   11633 
   11634     switch (aNodeResp.GetCmdStatus())
   11635     {
   11636         case PVMFSuccess:
   11637             if (iSourceNodePVInterfaceInit)
   11638             {
   11639                 iSourceNodeInitIF = (PVMFDataSourceInitializationExtensionInterface*)iSourceNodePVInterfaceInit;
   11640                 iSourceNodePVInterfaceInit = NULL;
   11641             }
   11642             // Query for track selection interface
   11643             cmdstatus = DoSourceNodeQueryTrackSelIF(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   11644             if (cmdstatus != PVMFSuccess)
   11645             {
   11646                 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
   11647                 {
   11648                     iRollOverState = RollOverStateStart;
   11649                     rescheduleAO = true;
   11650                 }
   11651                 else
   11652                 {
   11653                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   11654                                     (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() DoSourceNodeQueryTrackSelIF failed, Add EH command"));
   11655                     iCommandCompleteStatusInErrorHandling = cmdstatus;
   11656                     iCommandCompleteErrMsgInErrorHandling = NULL;
   11657                     if (iRollOverState == RollOverStateInProgress)
   11658                     {
   11659                         // Init is the current ongoing cmd so queue Init EH cmd
   11660                         AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   11661                     }
   11662                     else
   11663                     {
   11664                         // AddDataSource cmd is Current Command, queue ADS EH cmd
   11665                         AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
   11666                     }
   11667                     iRollOverState = RollOverStateIdle;
   11668                 }
   11669             }
   11670             break;
   11671 
   11672         default:
   11673         {
   11674             iSourceNodePVInterfaceInit = NULL;
   11675             iSourceNodeInitIF = NULL;
   11676 
   11677             if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
   11678             {
   11679                 iRollOverState = RollOverStateStart;
   11680                 rescheduleAO = true;
   11681             }
   11682             else
   11683             {
   11684                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   11685                                 (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() failed, Add EH command"));
   11686                 cmdstatus = aNodeResp.GetCmdStatus();
   11687                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   11688                 if (aNodeResp.GetEventExtensionInterface())
   11689                 {
   11690                     nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   11691                 }
   11692 
   11693                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   11694                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
   11695                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   11696                 if (iRollOverState == RollOverStateInProgress)
   11697                 {
   11698                     // Init is the current ongoing cmd so queue Init EH cmd
   11699                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   11700                 }
   11701                 else
   11702                 {
   11703                     // AddDataSource cmd is Current Command, queue ADS EH cmd
   11704                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
   11705                 }
   11706                 iRollOverState = RollOverStateIdle;
   11707             }
   11708         }
   11709         break;
   11710     }
   11711     if (rescheduleAO)
   11712     {
   11713         if (IsBusy())
   11714         {
   11715             Cancel();
   11716         }
   11717 
   11718         RunIfNotReady();
   11719     }
   11720 
   11721     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() Out"));
   11722 }
   11723 
   11724 
   11725 void PVPlayerEngine::HandleSourceNodeQueryTrackSelIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   11726 {
   11727     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   11728                     (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() Tick=%d", OsclTickCount::TickCount()));
   11729 
   11730     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() In"));
   11731 
   11732     PVMFStatus cmdstatus;
   11733     bool rescheduleAO = false;
   11734 
   11735     switch (aNodeResp.GetCmdStatus())
   11736     {
   11737         case PVMFSuccess:
   11738             if (iSourceNodePVInterfaceTrackSel)
   11739             {
   11740                 iSourceNodeTrackSelIF = (PVMFTrackSelectionExtensionInterface*)iSourceNodePVInterfaceTrackSel;
   11741                 iSourceNodePVInterfaceTrackSel = NULL;
   11742             }
   11743             // Query the source node for optional extension IFs
   11744             cmdstatus = DoSourceNodeQueryInterfaceOptional(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   11745             if (cmdstatus != PVMFSuccess)
   11746             {
   11747                 // If optional extension IFs are not available, just complete the AddDataSource command as success
   11748                 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
   11749                 {
   11750                     iRollOverState = RollOverStateStart;
   11751                     rescheduleAO = true;
   11752                 }
   11753                 else
   11754                 {
   11755                     iRollOverState = RollOverStateIdle;
   11756                     EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   11757                 }
   11758             }
   11759             break;
   11760 
   11761         default:
   11762         {
   11763             iSourceNodePVInterfaceTrackSel = NULL;
   11764             iSourceNodeTrackSelIF = NULL;
   11765 
   11766             if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
   11767             {
   11768                 iRollOverState = RollOverStateStart;
   11769                 rescheduleAO = true;
   11770             }
   11771             else
   11772             {
   11773                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   11774                                 (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() failed, Add EH Command"));
   11775                 cmdstatus = aNodeResp.GetCmdStatus();
   11776                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   11777                 if (aNodeResp.GetEventExtensionInterface())
   11778                 {
   11779                     nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   11780                 }
   11781 
   11782                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   11783                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
   11784 
   11785                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   11786                 if (iRollOverState == RollOverStateInProgress)
   11787                 {
   11788                     // Init is the current ongoing cmd so queue Init EH cmd
   11789                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   11790                 }
   11791                 else
   11792                 {
   11793                     // AddDataSource cmd is Current Command, queue ADS EH cmd
   11794                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
   11795                 }
   11796                 iRollOverState = RollOverStateIdle;
   11797             }
   11798         }
   11799         break;
   11800     }
   11801     if (rescheduleAO)
   11802     {
   11803         if (IsBusy())
   11804         {
   11805             Cancel();
   11806         }
   11807 
   11808         RunIfNotReady();
   11809     }
   11810     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() Out"));
   11811 }
   11812 
   11813 
   11814 void PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   11815 {
   11816     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   11817                     (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
   11818 
   11819     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() In"));
   11820 
   11821     // Determine QueryInterface() for which interface completed
   11822     if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryTrackLevelInfoIF)
   11823     {
   11824         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceTrackLevelInfo)
   11825         {
   11826             iSourceNodeTrackLevelInfoIF = (PVMFTrackLevelInfoExtensionInterface*)iSourceNodePVInterfaceTrackLevelInfo;
   11827             iSourceNodePVInterfaceTrackLevelInfo = NULL;
   11828         }
   11829         else
   11830         {
   11831             // Track level info IF is not available in this data source
   11832             iSourceNodePVInterfaceTrackLevelInfo = NULL;
   11833             iSourceNodeTrackLevelInfoIF = NULL;
   11834             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Track level info IF not available"));
   11835         }
   11836     }
   11837     else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryPBCtrlIF)
   11838     {
   11839         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfacePBCtrl)
   11840         {
   11841             iSourceNodePBCtrlIF = (PvmfDataSourcePlaybackControlInterface*)iSourceNodePVInterfacePBCtrl;
   11842             iSourceNodePVInterfacePBCtrl = NULL;
   11843         }
   11844         else
   11845         {
   11846             // Playback control is not available in this data source
   11847             iSourceNodePVInterfacePBCtrl = NULL;
   11848             iSourceNodePBCtrlIF = NULL;
   11849             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Position control IF not available"));
   11850         }
   11851     }
   11852     else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryDirCtrlIF)
   11853     {
   11854         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceDirCtrl)
   11855         {
   11856             iSourceNodeDirCtrlIF = (PvmfDataSourceDirectionControlInterface*)iSourceNodePVInterfaceDirCtrl;
   11857             iSourceNodePVInterfaceDirCtrl = NULL;
   11858         }
   11859         else
   11860         {
   11861             // Direction control is not available in this data source
   11862             iSourceNodePVInterfaceDirCtrl = NULL;
   11863             iSourceNodeDirCtrlIF = NULL;
   11864             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Direction control IF not available"));
   11865         }
   11866     }
   11867     else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryMetadataIF)
   11868     {
   11869         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceMetadataExt)
   11870         {
   11871             iSourceNodeMetadataExtIF = (PVMFMetadataExtensionInterface*)iSourceNodePVInterfaceMetadataExt;
   11872             iSourceNodePVInterfaceMetadataExt = NULL;
   11873 
   11874             // Add the parser node's metadata extension IF to the list
   11875             if (AddToMetadataInterfaceList(iSourceNodeMetadataExtIF, iSourceNodeSessionId, NULL, iSourceNode) != PVMFSuccess)
   11876             {
   11877                 iSourceNodeMetadataExtIF->removeRef();
   11878                 iSourceNodeMetadataExtIF = NULL;
   11879 
   11880                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Metadata IF could not be added to list"));
   11881             }
   11882         }
   11883         else
   11884         {
   11885             // Metadata is not available in this data source
   11886             iSourceNodePVInterfaceMetadataExt = NULL;
   11887             iSourceNodeMetadataExtIF = NULL;
   11888             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Metadata IF not available"));
   11889         }
   11890     }
   11891     else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryCapConfigIF)
   11892     {
   11893         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceCapConfig)
   11894         {
   11895             iSourceNodeCapConfigIF = (PvmiCapabilityAndConfig*)iSourceNodePVInterfaceCapConfig;
   11896             iSourceNodePVInterfaceCapConfig = NULL;
   11897         }
   11898         else
   11899         {
   11900             // Cap-config is not available in this data source
   11901             iSourceNodePVInterfaceCapConfig = NULL;
   11902             iSourceNodeCapConfigIF = NULL;
   11903             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Cap-Config IF not available"));
   11904         }
   11905     }
   11906     else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryCPMLicenseIF)
   11907     {
   11908         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceCPMLicense)
   11909         {
   11910             iSourceNodeCPMLicenseIF = (PVMFCPMPluginLicenseInterface*)iSourceNodePVInterfaceCPMLicense;
   11911             iSourceNodePVInterfaceCPMLicense = NULL;
   11912         }
   11913         else
   11914         {
   11915             //CPM License is not available in this data source
   11916             iSourceNodePVInterfaceCPMLicense = NULL;
   11917             iSourceNodeCPMLicenseIF = NULL;
   11918             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() CPM License IF not available"));
   11919         }
   11920     }
   11921     else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQuerySrcNodeRegInitIF)
   11922     {
   11923         if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceRegInit)
   11924         {
   11925             iSourceNodeRegInitIF = (PVMFDataSourceNodeRegistryInitInterface*)iSourceNodePVInterfaceRegInit;
   11926             iSourceNodePVInterfaceRegInit = NULL;
   11927 
   11928             // Set source node regsitry
   11929             iSourceNodeRegInitIF->SetPlayerNodeRegistry(&iPlayerNodeRegistry);
   11930         }
   11931         else
   11932         {
   11933             //Node Registry Init Extension Interface is not available in this data source
   11934             iSourceNodePVInterfaceRegInit = NULL;
   11935             iSourceNodeRegInitIF = NULL;
   11936             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Src Node Registry Init IF not available"));
   11937         }
   11938     }
   11939 
   11940     // Decrement the pending counter and complete the AddDataSource command if 0.
   11941     --iNumPendingNodeCmd;
   11942     if (iNumPendingNodeCmd == 0)
   11943     {
   11944         if (iRollOverState == RollOverStateInProgress)
   11945         {
   11946             SetRollOverKVPValues();
   11947             PVMFStatus retval = DoSourceNodeInit(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   11948             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() - Source Roll Over In Progress - Doing Source Node Init"));
   11949 
   11950             if (retval == PVMFSuccess)
   11951             {
   11952                 SetEngineState(PVP_ENGINE_STATE_INITIALIZING);
   11953             }
   11954             else
   11955             {
   11956                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() - Source Roll Over In Progress - DoSourceNodeInit Failed"));
   11957                 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
   11958                 {
   11959                     iRollOverState = RollOverStateStart;
   11960                     RunIfNotReady();
   11961                 }
   11962                 else
   11963                 {
   11964                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   11965                                     (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() DoSourceNodeInit failed, Add EH Command"));
   11966                     iRollOverState = RollOverStateIdle;
   11967                     iCommandCompleteStatusInErrorHandling = retval;
   11968                     iCommandCompleteErrMsgInErrorHandling = NULL;
   11969                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   11970                 }
   11971             }
   11972         }
   11973         else
   11974         {
   11975             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() All QueryInterface() commands complete so AddDataSource is complete"));
   11976             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   11977         }
   11978     }
   11979     else
   11980     {
   11981         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() %d QueryInterface() commands are still pending", iNumPendingNodeCmd));
   11982     }
   11983 
   11984     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Out"));
   11985 }
   11986 
   11987 void PVPlayerEngine::HandleSourceNodeInit(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   11988 {
   11989     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   11990                     (0, "PVPlayerEngine::HandleSourceNodeInit() Tick=%d", OsclTickCount::TickCount()));
   11991 
   11992     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInit() In"));
   11993 
   11994     iRollOverState = RollOverStateIdle;
   11995     PVMFStatus cmdstatus;
   11996 
   11997     switch (aNodeResp.GetCmdStatus())
   11998     {
   11999         case PVMFSuccess:
   12000         {
   12001             // Try to retrieve the duration from the source node via metadata IF
   12002             // Only if we din't got that value through PVMFInfoDurationAvailable informational event.
   12003             if (!iSourceDurationAvailable)
   12004             {
   12005                 if (DoSourceNodeGetDurationValue(aNodeContext.iCmdId, aNodeContext.iCmdContext) != PVMFSuccess)
   12006                 {
   12007                     // Duration could not be retrieved.
   12008                     // Not an error so complete so engine's Init()
   12009                     SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
   12010                     EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   12011                 }
   12012             }
   12013             else
   12014             {
   12015                 // Duration is already available through Info event.
   12016                 // so complete  engine's Init()
   12017                 SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
   12018                 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   12019             }
   12020         }
   12021         break;
   12022 
   12023 
   12024         case PVMFErrLicenseRequired:
   12025         case PVMFErrHTTPAuthenticationRequired:
   12026         case PVMFErrRedirect:
   12027         {
   12028             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInit() PVMFErrLicenseRequired/PVMFErrHTTPAuthenticationRequired/PVMFErrRedirect"));
   12029 
   12030             SetEngineState(PVP_ENGINE_STATE_IDLE);
   12031             cmdstatus = aNodeResp.GetCmdStatus();
   12032 
   12033             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   12034             if (aNodeResp.GetEventExtensionInterface())
   12035             {
   12036                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   12037             }
   12038 
   12039             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   12040             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
   12041 
   12042             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg), aNodeResp.GetEventData());
   12043             errmsg->removeRef();
   12044 
   12045         }
   12046         break;
   12047         case PVMFErrContentInvalidForProgressivePlayback:
   12048         {
   12049             SetEngineState(PVP_ENGINE_STATE_ERROR);
   12050             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   12051 
   12052             cmdstatus = aNodeResp.GetCmdStatus();
   12053 
   12054             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   12055             if (aNodeResp.GetEventExtensionInterface())
   12056             {
   12057                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   12058             }
   12059 
   12060             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   12061             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
   12062             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg), aNodeResp.GetEventData());
   12063             errmsg->removeRef();
   12064         }
   12065         break;
   12066 
   12067         default:
   12068         {
   12069             if (iState == PVP_ENGINE_STATE_INITIALIZING)
   12070             {
   12071                 SetEngineState(PVP_ENGINE_STATE_IDLE);
   12072                 if (CheckForSourceRollOver() == false)
   12073                 {
   12074                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() failed, Add EH Command"));
   12075                     cmdstatus = aNodeResp.GetCmdStatus();
   12076 
   12077                     PVMFErrorInfoMessageInterface* nextmsg = NULL;
   12078                     if (aNodeResp.GetEventExtensionInterface())
   12079                     {
   12080                         nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   12081                     }
   12082 
   12083                     PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   12084                     iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
   12085                     iCommandCompleteStatusInErrorHandling = cmdstatus;
   12086                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
   12087                 }
   12088                 else
   12089                 {
   12090                     // Initialization of source node failed so try alternates
   12091                     //reschedule to do source node roll over
   12092                     iRollOverState = RollOverStateStart;
   12093                     //remove any queued up auto-pause/auto-resume commands
   12094                     //they are no longer applicable since we are doing a change of sourcenode
   12095                     removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, true);
   12096                     removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, true);
   12097                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() - Rescheduling to do source roll over"));
   12098                     RunIfNotReady();
   12099                 }
   12100             }
   12101             else
   12102             {
   12103                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() - Incorrect State - Asserting"));
   12104                 OSCL_ASSERT(false);
   12105             }
   12106         }
   12107         break;
   12108     }
   12109 
   12110     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInit() Out"));
   12111 }
   12112 
   12113 
   12114 void PVPlayerEngine::HandleSourceNodeGetDurationValue(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12115 {
   12116     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12117                     (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Tick=%d", OsclTickCount::TickCount()));
   12118 
   12119     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() In"));
   12120 
   12121     switch (aNodeResp.GetCmdStatus())
   12122     {
   12123         case PVMFSuccess:
   12124         {
   12125             // Extract the duration and save it
   12126             // Check that there is one KVP in value list
   12127             if (iSourceDurationValueList.size() != 1)
   12128             {
   12129                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Value list size is not 1 (size=%d)",
   12130                                 iSourceDurationValueList.size()));
   12131                 break;
   12132             }
   12133 
   12134             // Check that the key in KVP is not NULL
   12135             if (iSourceDurationValueList[0].key == NULL)
   12136             {
   12137                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Value list key string is NULL"));
   12138                 break;
   12139             }
   12140 
   12141             // Check that value is for duration
   12142             int retval = pv_mime_strstr(iSourceDurationValueList[0].key, (char*)_STRLIT_CHAR("duration"));
   12143             if (retval == -1)
   12144             {
   12145                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Key string does not contain duration"));
   12146                 break;
   12147             }
   12148 
   12149             // Check that duration value is uint32. If not available assume uint32.
   12150             PvmiKvpValueType durvaltype = GetValTypeFromKeyString(iSourceDurationValueList[0].key);
   12151             if (durvaltype != PVMI_KVPVALTYPE_UINT32 && durvaltype != PVMI_KVPVALTYPE_UNKNOWN)
   12152             {
   12153                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Value type is not uint32 or unknown"));
   12154                 break;
   12155             }
   12156             iSourceDurationInMS = iSourceDurationValueList[0].value.uint32_value;
   12157 
   12158             // Check the timescale. If not available, assume millisecond (1000)
   12159             const char* retsubstr = NULL;
   12160             uint32 retsubstrlen = 0;
   12161             uint32 tsparamlen = oscl_strlen(_STRLIT_CHAR("timescale="));
   12162             retsubstr = oscl_strstr(iSourceDurationValueList[0].key, _STRLIT_CHAR("timescale="));
   12163             if (retsubstr != NULL)
   12164             {
   12165                 retsubstrlen = oscl_strlen(retsubstr);
   12166                 if (retsubstrlen > tsparamlen)
   12167                 {
   12168                     uint32 timescale = 0;
   12169                     PV_atoi((char*)(retsubstr + tsparamlen), 'd', (retsubstrlen - tsparamlen), timescale);
   12170                     if (timescale > 0 && timescale != 1000)
   12171                     {
   12172                         // Convert to milliseconds
   12173                         MediaClockConverter mcc(timescale);
   12174                         mcc.update_clock(iSourceDurationInMS);
   12175                         iSourceDurationInMS = mcc.get_converted_ts(1000);
   12176                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Timescale for duration is %d",
   12177                                         timescale));
   12178                     }
   12179                 }
   12180             }
   12181 
   12182             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Duration in millisec is %d",
   12183                             iSourceDurationInMS));
   12184             iSourceDurationAvailable = true;
   12185         }
   12186         break;
   12187 
   12188         default:
   12189         {
   12190             // Duration is not available
   12191             // Do nothing
   12192         }
   12193         break;
   12194     }
   12195 
   12196     // Release any metadata values back to source node
   12197     // and then clear it
   12198     if (iSourceDurationValueList.empty() == false)
   12199     {
   12200         if (iSourceNodeMetadataExtIF != NULL)
   12201         {
   12202             iSourceNodeMetadataExtIF->ReleaseNodeMetadataValues(iSourceDurationValueList, 0, iSourceDurationValueList.size());
   12203         }
   12204         iSourceDurationValueList.clear();
   12205     }
   12206 
   12207     // Engine's Init() is now complete
   12208     SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
   12209     EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   12210 
   12211     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Out"));
   12212 }
   12213 
   12214 void PVPlayerEngine::HandleSourceNodeSetDataSourceRate(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12215 {
   12216     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceRate() In"));
   12217 
   12218     PVMFStatus cmdstatus = aNodeResp.GetCmdStatus();
   12219 
   12220     if (cmdstatus != PVMFSuccess)
   12221     {
   12222         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus);
   12223     }
   12224     else
   12225     {
   12226         //Continue on to sink rate change.
   12227         cmdstatus = DoSinkNodeChangeClockRate();
   12228         if (cmdstatus != PVMFSuccess)
   12229         {
   12230             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus);
   12231         }
   12232         else
   12233         {
   12234             //Rate Change is complete.
   12235 
   12236             //Install the updated rate and timebase.
   12237             UpdateTimebaseAndRate();
   12238 
   12239             //Start direction change sequence if needed.
   12240             if (iPlaybackDirection_New != iPlaybackDirection)
   12241             {
   12242                 cmdstatus = UpdateCurrentDirection(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12243                 switch (cmdstatus)
   12244                 {
   12245                     case PVMFPending:
   12246                         //wait on node command completion and call to HandleSourceNodeSetDataSourceDirection
   12247                         break;
   12248                     case PVMFSuccess:
   12249                         //engine command is done, but direction is not actually set on the
   12250                         //source until the Resume or Prepare happens.
   12251                         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   12252                         break;
   12253                     default:
   12254                         //failed!
   12255                         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus);
   12256                         break;
   12257                 }
   12258             }
   12259             else
   12260             {
   12261                 //SetPlaybackRate is complete!
   12262                 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   12263             }
   12264         }
   12265     }
   12266 
   12267     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceRate() Out"));
   12268 }
   12269 
   12270 PVMFStatus PVPlayerEngine::DoSinkNodeChangeClockRate()
   12271 {
   12272     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeChangeClockRate() In"));
   12273 
   12274     // Check with sink nodes
   12275     PVMFStatus cmdstatus = PVMFSuccess;
   12276 
   12277     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   12278     {
   12279         if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   12280         {
   12281             cmdstatus = iDatapathList[i].iSinkNodeSyncCtrlIF->ChangeClockRate(iPlaybackClockRate_New);
   12282 
   12283             if (cmdstatus != PVMFSuccess)
   12284             {
   12285                 // One of the sinks reported not supported so don't allow the clock rate change.
   12286                 break;
   12287             }
   12288         }
   12289     }
   12290 
   12291     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeChangeClockRate() Out"));
   12292     return cmdstatus;
   12293 }
   12294 
   12295 void PVPlayerEngine::UpdateDirection(PVMFTimestamp aNPT, PVMFTimestamp aMediaTS, PVPPlaybackPosition& aPos)
   12296 {
   12297     //First note the current observed NPT value.  We will reposition to this
   12298     //value.
   12299     PVPPlaybackPosition curpos;
   12300     curpos.iIndeterminate = false;
   12301     curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   12302     GetPlaybackClockPosition(curpos);
   12303     aPos = curpos;
   12304 
   12305     //Install the new value for direction.
   12306     iPlaybackDirection = iPlaybackDirection_New;
   12307 
   12308     //Save the start NPT and TS
   12309     iStartNPT = aNPT;
   12310     iStartMediaDataTS = aMediaTS;
   12311 
   12312     if (iPlaybackDirection_New < 0)
   12313     {
   12314         if (aPos.iPosValue.millisec_value >= iSourceDurationInMS)
   12315         {
   12316             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateDirection() Current pos %dms is more than Duration %dms", aPos.iPosValue.millisec_value, iSourceDurationInMS));
   12317             if (ConvertFromMillisec((uint32)(iSourceDurationInMS - 1), aPos) != PVMFSuccess)
   12318             {
   12319                 // Other position units are not supported yet
   12320                 aPos.iIndeterminate = true;
   12321             }
   12322         }
   12323     }
   12324 
   12325     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   12326                     (0, "PVPlayerEngine::UpdateDirection() Direction %d New Start NPT %d Start Media Data TS %d, Repos NPT %d, Pos Indeterminate %d"
   12327                      , iPlaybackDirection
   12328                      , iStartNPT
   12329                      , iStartMediaDataTS
   12330                      , aPos.iPosValue.millisec_value
   12331                      , aPos.iIndeterminate));
   12332 }
   12333 
   12334 void PVPlayerEngine::UpdateTimebaseAndRate()
   12335 {
   12336     if (iPlaybackClockRate_New == iPlaybackClockRate
   12337             && iOutsideTimebase_New == iOutsideTimebase)
   12338         return;//no update needed
   12339 
   12340     //Install the new values for rate & timebase.
   12341     iPlaybackClockRate = iPlaybackClockRate_New;
   12342     iOutsideTimebase = iOutsideTimebase_New;
   12343 
   12344     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   12345                     (0, "PVPlayerEngine::UpdateTimebaseAndRate() Rate %d OutsideTB 0x%x CurDir %d NewDir %d"
   12346                      , iPlaybackClockRate, iOutsideTimebase
   12347                      , iPlaybackDirection, iPlaybackDirection_New));
   12348 
   12349     // Pause the clock if running. If already stopped or paused, the call would fail
   12350     bool clockpaused = iPlaybackClock.Pause();
   12351 
   12352     if (iOutsideTimebase)
   12353     {
   12354         //use the outside timebase & ignore the rate.
   12355         iPlaybackClock.SetClockTimebase(*iOutsideTimebase);
   12356     }
   12357     else
   12358     {
   12359         //use the player timebase and set the rate.
   12360         iPlaybackTimebase.SetRate(iPlaybackClockRate);
   12361         iPlaybackClock.SetClockTimebase(iPlaybackTimebase);
   12362     }
   12363 
   12364     // Only restart the clock if the clock was paused in this function
   12365     if (clockpaused)
   12366     {
   12367         StartPlaybackClock();
   12368     }
   12369 }
   12370 
   12371 void PVPlayerEngine::HandleSinkNodeQueryCapConfigIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12372 {
   12373     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12374                     (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Tick=%d", OsclTickCount::TickCount()));
   12375 
   12376     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() In"));
   12377 
   12378     switch (aNodeResp.GetCmdStatus())
   12379     {
   12380         case PVMFSuccess:
   12381         {
   12382             if (aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig)
   12383             {
   12384                 aNodeContext.iEngineDatapath->iSinkNodeCapConfigIF = (PvmiCapabilityAndConfig*)aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig;
   12385                 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig = NULL;
   12386             }
   12387         }
   12388         break;
   12389 
   12390         default:
   12391         {
   12392             if (aNodeContext.iNode == aNodeContext.iEngineDatapath->iSinkNode)
   12393             {
   12394                 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig = NULL;
   12395                 aNodeContext.iEngineDatapath->iSinkNodeCapConfigIF = NULL;
   12396             }
   12397             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12398                             (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Node dont support Cap-Config Interface, ignoring"));
   12399         }
   12400         break;
   12401     }
   12402 
   12403     // Decrement the pending counter and go to next step if 0.
   12404     --iNumPendingNodeCmd;
   12405     if (iNumPendingNodeCmd == 0)
   12406     {
   12407         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   12408                         (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() All QueryInterface() commands complete"));
   12409 
   12410         PVMFStatus cmdstatus = DoSinkNodeInit(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12411         if (cmdstatus != PVMFSuccess)
   12412         {
   12413             bool ehPending = CheckForPendingErrorHandlingCmd();
   12414             if (ehPending)
   12415             {
   12416                 // there should be no error handling queued.
   12417                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Already EH pending, should never happen"));
   12418                 return;
   12419             }
   12420             else
   12421             {
   12422                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12423                                 (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() DoSinkNodeInit failed, Add EH Command"));
   12424                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   12425                 iCommandCompleteErrMsgInErrorHandling = NULL;
   12426                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12427             }
   12428         }
   12429     }
   12430 
   12431     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Out"));
   12432 }
   12433 
   12434 void PVPlayerEngine::HandleSinkNodeInit(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12435 {
   12436     OSCL_UNUSED_ARG(aNodeContext);
   12437     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12438                     (0, "PVPlayerEngine::HandleSinkNodeInit() Tick=%d", OsclTickCount::TickCount()));
   12439 
   12440     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInit() In"));
   12441 
   12442     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   12443     {
   12444         bool ehPending = CheckForPendingErrorHandlingCmd();
   12445         if (ehPending)
   12446         {
   12447             // there should be no error handling queued.
   12448             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeInit() Already EH pending, should never happen"));
   12449             return;
   12450         }
   12451         else
   12452         {
   12453             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12454                             (0, "PVPlayerEngine::HandleSinkNodeInit() cmd response is failure, Add EH Command"));
   12455             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   12456             if (aNodeResp.GetEventExtensionInterface())
   12457             {
   12458                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   12459             }
   12460 
   12461             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   12462             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkInit, puuid, nextmsg));
   12463             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   12464             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12465             return;
   12466         }
   12467     }
   12468 
   12469     // Decrement the pending counter and go to next step if 0.
   12470     --iNumPendingNodeCmd;
   12471     if (iNumPendingNodeCmd == 0)
   12472     {
   12473         // Init on sink nodes is complete, next step in track selection is to check with the sink nodes alone if the track is
   12474         // playable or not. If track can be played using sink nodes only move to track selection or else go further to
   12475         // instantiate decoder nodes for the tracks.
   12476 
   12477         // set the Engine state to Track selection so that engine calls DoPrepare and do further processing in Track selection
   12478 
   12479         SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE);
   12480         RunIfNotReady();
   12481     }
   12482 
   12483     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInit() Out"));
   12484 
   12485     return;
   12486 }
   12487 
   12488 void PVPlayerEngine::HandleDecNodeQueryCapConfigIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12489 {
   12490     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12491                     (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Tick=%d", OsclTickCount::TickCount()));
   12492 
   12493     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() In"));
   12494 
   12495     for (uint32 i = 0; i < iTrackSelectionList.size(); i++)
   12496     {
   12497         switch (aNodeResp.GetCmdStatus())
   12498         {
   12499             case PVMFSuccess:
   12500             {
   12501                 if (aNodeContext.iNode == iTrackSelectionList[i].iTsDecNode && iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig)
   12502                 {
   12503                     iTrackSelectionList[i].iTsDecNodeCapConfigIF = (PvmiCapabilityAndConfig*)iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig;
   12504                     iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
   12505 
   12506                     PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
   12507                     // Valid decoder node set in TrackSelectionList. Scan the TrackSelectionList further and if
   12508                     // any similar MIME track is present just set the decoders to NULL for now.
   12509                     // This is to avoid multiple Init calls on same decoder nodes for similar tracks.
   12510                     // Set the decoder nodes and its cap and config I/F once decoder node Inits complete.
   12511                     for (uint32 j = i + 1; j < iTrackSelectionList.size(); j++)
   12512                     {
   12513                         PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(j);
   12514                         if (!(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())))
   12515                         {
   12516                             // These were earlier set in DoDecNodeQueryCapConfifIF to avoid multiple creation of same
   12517                             // decoder nodes.
   12518                             iTrackSelectionList[j].iTsDecNode = NULL;
   12519                             iTrackSelectionList[j].iTsDecNodeSessionId = 0;
   12520                             iTrackSelectionList[j].iTsDecNodeCapConfigIF = NULL;
   12521                         }
   12522                     }
   12523                 }
   12524             }
   12525             break;
   12526 
   12527             default:
   12528             {
   12529                 if (aNodeContext.iNode == iTrackSelectionList[i].iTsDecNode)
   12530                 {
   12531                     iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
   12532                     iTrackSelectionList[i].iTsDecNodeCapConfigIF = NULL;
   12533                 }
   12534                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12535                                 (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Node dont support Cap-Config Interface, ignoring"));
   12536             }
   12537             break;
   12538         }
   12539     }
   12540 
   12541     // Decrement the pending counter and go to next step if 0.
   12542     --iNumPendingNodeCmd;
   12543     if (iNumPendingNodeCmd == 0)
   12544     {
   12545         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   12546                         (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() All QueryInterface() commands complete"));
   12547 
   12548         PVMFStatus cmdstatus = DoDecNodeInit(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12549         if (cmdstatus != PVMFSuccess)
   12550         {
   12551             bool ehPending = CheckForPendingErrorHandlingCmd();
   12552             if (ehPending)
   12553             {
   12554                 // there should be no error handling queued.
   12555                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Already EH pending, should never happen"));
   12556                 return;
   12557             }
   12558             else
   12559             {
   12560                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12561                                 (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() DoDecNodeInit failed, Add EH Command"));
   12562                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   12563                 iCommandCompleteErrMsgInErrorHandling = NULL;
   12564                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12565             }
   12566         }
   12567     }
   12568 
   12569     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Out"));
   12570 }
   12571 
   12572 void PVPlayerEngine::HandleDecNodeInit(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12573 {
   12574     OSCL_UNUSED_ARG(aNodeContext);
   12575     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12576                     (0, "PVPlayerEngine::HandleDecNodeInit() Tick=%d", OsclTickCount::TickCount()));
   12577 
   12578     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInit() In"));
   12579 
   12580     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   12581     {
   12582         bool ehPending = CheckForPendingErrorHandlingCmd();
   12583         if (ehPending)
   12584         {
   12585             // there should be no error handling queued.
   12586             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeInit() Already EH pending, should never happen"));
   12587             return;
   12588         }
   12589         else
   12590         {
   12591             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12592                             (0, "PVPlayerEngine::HandleDecNodeInit() cmd response is failure, Add EH Command"));
   12593             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   12594             if (aNodeResp.GetEventExtensionInterface())
   12595             {
   12596                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   12597             }
   12598 
   12599             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   12600             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapath, puuid, nextmsg));
   12601             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   12602             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12603             return;
   12604         }
   12605     }
   12606 
   12607     // Decrement the pending counter and go to next step if 0.
   12608     --iNumPendingNodeCmd;
   12609     if (iNumPendingNodeCmd == 0)
   12610     {
   12611         // All decoder node Init is complete, now set the decoder node for similar tracks in TrackSelectionList.
   12612         for (uint32 i = 0; i < iTrackSelectionList.size(); i++)
   12613         {
   12614             PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
   12615 
   12616             for (uint32 j = i + 1; j < iTrackSelectionList.size(); j++)
   12617             {
   12618                 // If the track has the same MIME type and needs to have a decoder node for it to be playabale track
   12619                 // use the already created decoder node for the track.
   12620                 PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(j);
   12621 
   12622                 if ((iTrackSelectionList[i].iTsDecNode != NULL) &&
   12623                         !(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())) &&
   12624                         !(iTrackSelectionList[j].iTsTrackValidForPlayableList))
   12625                 {
   12626                     // These were earlier set in DoDecNodeQueryCapConfifIF to avoid multiple creation of same
   12627                     // decoder nodes.
   12628                     iTrackSelectionList[j].iTsDecNode = iTrackSelectionList[i].iTsDecNode;
   12629                     iTrackSelectionList[j].iTsDecNodeSessionId = iTrackSelectionList[i].iTsDecNodeSessionId;
   12630                     iTrackSelectionList[j].iTsDecNodeCapConfigIF = iTrackSelectionList[i].iTsDecNodeCapConfigIF;
   12631                 }
   12632             }
   12633         }
   12634 
   12635         // Now engine has all decoder and sink nodes setup for each valid track. Engine will now do the track selection based
   12636         // on config paramters of each track
   12637 
   12638         SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE);
   12639         RunIfNotReady();
   12640     }
   12641     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInit() Out"));
   12642     return;
   12643 }
   12644 
   12645 void PVPlayerEngine::HandleSourceNodePrepare(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12646 {
   12647     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   12648                     (0, "PVPlayerEngine::HandleSourceNodePrepare() Tick=%d", OsclTickCount::TickCount()));
   12649 
   12650     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePrepare() In"));
   12651 
   12652     PVMFStatus cmdstatus = PVMFErrNotSupported;
   12653 
   12654     switch (aNodeResp.GetCmdStatus())
   12655     {
   12656         case PVMFSuccess:
   12657         {
   12658             // Datapaths are already set during intelligent track selection, just query for optional interfaces.
   12659             iNumPendingDatapathCmd = 0;
   12660             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   12661             {
   12662                 if (iDatapathList[i].iTrackInfo != NULL)
   12663                 {
   12664                     PVMFStatus retcode = DoSinkNodeQueryInterfaceOptional(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12665                     if (retcode == PVMFSuccess)
   12666                     {
   12667                         ++iNumPendingDatapathCmd;
   12668                         cmdstatus = PVMFSuccess;
   12669                     }
   12670                     else
   12671                     {
   12672                         cmdstatus = retcode;
   12673                     }
   12674                 }
   12675             }
   12676 
   12677             if (iNumPendingDatapathCmd == 0)
   12678             {
   12679                 if (cmdstatus == PVMFErrNotSupported)
   12680                 {
   12681                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePrepare() No datapath could be setup. Asserting"));
   12682                     OSCL_ASSERT(false);
   12683                 }
   12684                 bool ehPending = CheckForPendingErrorHandlingCmd();
   12685                 if (ehPending)
   12686                 {
   12687                     // there should be no error handling queued.
   12688                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePrepare() Already EH pending, should never happen"));
   12689                     return;
   12690                 }
   12691                 else
   12692                 {
   12693                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12694                                     (0, "PVPlayerEngine::HandleSourceNodePrepare() Report command as failed, Add EH Command"));
   12695                     iCommandCompleteStatusInErrorHandling = cmdstatus;
   12696                     iCommandCompleteErrMsgInErrorHandling = NULL;
   12697                     AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12698                 }
   12699             }
   12700         }
   12701         break;
   12702 
   12703         default:
   12704         {
   12705             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12706                             (0, "PVPlayerEngine::HandleSourceNodePrepare() failed, Add EH Command"));
   12707             bool ehPending = CheckForPendingErrorHandlingCmd();
   12708             if (ehPending)
   12709             {
   12710                 // there should be no error handling queued.
   12711                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePrepare() Already EH pending, should never happen"));
   12712                 return;
   12713             }
   12714             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   12715             if (aNodeResp.GetEventExtensionInterface())
   12716             {
   12717                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   12718             }
   12719 
   12720             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   12721             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   12722             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   12723 
   12724             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12725         }
   12726         break;
   12727     }
   12728 
   12729     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePrepare() Out"));
   12730 }
   12731 
   12732 void PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12733 {
   12734     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12735                     (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
   12736 
   12737     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   12738 
   12739     // Determine QueryInterface() for which interface completed
   12740     if (aNodeContext.iCmdType == PVP_CMD_SinkNodeQuerySyncCtrlIF)
   12741     {
   12742         if (aNodeResp.GetCmdStatus() == PVMFSuccess && aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl)
   12743         {
   12744             aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF = (PvmfNodesSyncControlInterface*)aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl;
   12745             aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl = NULL;
   12746 
   12747             // Pass the playback clock to the sync control
   12748             aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetClock(&iPlaybackClock);
   12749 
   12750             // Set the sync margin, find corresponding track for the datapath using mime string
   12751             bool videoTrack = false;
   12752             bool audioTrack = false;
   12753             bool textTrack = false;
   12754             bool retVal = FindTrackForDatapathUsingMimeString(videoTrack, audioTrack, textTrack, aNodeContext.iEngineDatapath);
   12755             if (textTrack && retVal)
   12756             {
   12757                 // Text track
   12758                 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginText.min), iSyncMarginText.max);
   12759             }
   12760             else if (audioTrack && retVal)
   12761             {
   12762                 // Audio track
   12763                 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginAudio.min), iSyncMarginAudio.max);
   12764             }
   12765             else
   12766             {
   12767                 // Video track available or an unknown datapath
   12768                 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginVideo.min), iSyncMarginVideo.max);
   12769             }
   12770         }
   12771         else
   12772         {
   12773             // sync control interface is not available in this sink node
   12774             aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl = NULL;
   12775             aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF = NULL;
   12776             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Metadata IF not available"));
   12777             OSCL_ASSERT(false);
   12778         }
   12779     }
   12780     else if (aNodeContext.iCmdType == PVP_CMD_SinkNodeQueryMetadataIF)
   12781     {
   12782         if (aNodeResp.GetCmdStatus() == PVMFSuccess && aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt)
   12783         {
   12784             aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF = (PVMFMetadataExtensionInterface*)aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt;
   12785             aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt = NULL;
   12786 
   12787             // Add the video sink node's metadata extension IF to the list
   12788             if (AddToMetadataInterfaceList(aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF, aNodeContext.iEngineDatapath->iSinkNodeSessionId, aNodeContext.iEngineDatapath, aNodeContext.iEngineDatapath->iSinkNode) != PVMFSuccess)
   12789             {
   12790                 aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF->removeRef();
   12791                 aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF = NULL;
   12792                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Metadata IF could not be added to list"));
   12793             }
   12794         }
   12795         else
   12796         {
   12797             // Metadata is not available in this video sink node
   12798             aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt = NULL;
   12799             aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF = NULL;
   12800             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Metadata IF not available"));
   12801         }
   12802     }
   12803     else
   12804     {
   12805         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Unknown cmd type. Asserting"));
   12806         OSCL_ASSERT(false);
   12807     }
   12808 
   12809     // Decrement the pending counter and go to next step if 0.
   12810     --aNodeContext.iEngineDatapath->iNumPendingCmd;
   12811     if (aNodeContext.iEngineDatapath->iNumPendingCmd == 0)
   12812     {
   12813         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() All QueryInterface() commands complete"));
   12814 
   12815         // Create the decoder node if necessary
   12816         PVMFStatus cmdstatus = DoDecNodeQueryInterfaceOptional(*(aNodeContext.iEngineDatapath), aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12817         if (cmdstatus == PVMFErrNotSupported)
   12818         {
   12819             cmdstatus = DoDatapathPrepare(*(aNodeContext.iEngineDatapath), aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12820         }
   12821 
   12822         if (cmdstatus != PVMFSuccess)
   12823         {
   12824             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12825                             (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Report command as failed, Add EH Command"));
   12826             bool ehPending = CheckForPendingErrorHandlingCmd();
   12827             if (ehPending)
   12828             {
   12829                 // there should be no error handling queued.
   12830                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Already EH pending, should never happen"));
   12831                 return;
   12832             }
   12833             else
   12834             {
   12835                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   12836                 iCommandCompleteErrMsgInErrorHandling = NULL;
   12837                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12838             }
   12839         }
   12840     }
   12841 
   12842     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Out"));
   12843 }
   12844 
   12845 void PVPlayerEngine::HandleSinkNodeDecNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12846 {
   12847     OSCL_UNUSED_ARG(aNodeContext);
   12848     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12849                     (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() Tick=%d", OsclTickCount::TickCount()));
   12850 
   12851     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() In"));
   12852 
   12853     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   12854     {
   12855         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12856                         (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() Reset failed, assert"));
   12857         OSCL_ASSERT(false);
   12858         return;
   12859     }
   12860 
   12861     // Decrement the pending counter and go to next step if 0.
   12862     --iNumPendingNodeCmd;
   12863     if (iNumPendingNodeCmd == 0)
   12864     {
   12865         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() All Sinknode and decnode Reset() commands complete"));
   12866         SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE);
   12867         RunIfNotReady();
   12868     }
   12869 
   12870     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() Out"));
   12871 }
   12872 
   12873 void PVPlayerEngine::HandleDecNodeQueryInterfaceOptional(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12874 {
   12875     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
   12876                     (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
   12877 
   12878     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   12879 
   12880     // Determine QueryInterface() for which interface completed
   12881     if (aNodeContext.iCmdType == PVP_CMD_DecNodeQueryMetadataIF)
   12882     {
   12883         if (aNodeResp.GetCmdStatus() == PVMFSuccess && aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt)
   12884         {
   12885             aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF = (PVMFMetadataExtensionInterface*)aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt;
   12886             aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt = NULL;
   12887 
   12888             // Add the video dec node's metadata extension IF to the list
   12889             if (AddToMetadataInterfaceList(aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF, aNodeContext.iEngineDatapath->iDecNodeSessionId, aNodeContext.iEngineDatapath, aNodeContext.iEngineDatapath->iDecNode) != PVMFSuccess)
   12890             {
   12891                 aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF->removeRef();
   12892                 aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF = NULL;
   12893 
   12894                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Metadata IF could not be added to list"));
   12895             }
   12896         }
   12897         else
   12898         {
   12899             // Metadata is not available in this dec node
   12900             aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt = NULL;
   12901             aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF = NULL;
   12902             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Metadata IF not available"));
   12903         }
   12904     }
   12905     else
   12906     {
   12907         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Unknown cmd type. Asserting"));
   12908         OSCL_ASSERT(false);
   12909     }
   12910 
   12911     if (aNodeContext.iEngineDatapath->iDecNodeCapConfigIF)
   12912     {
   12913         // Configure the dec node for player use
   12914         PvmiKvp kvpparam;
   12915         PvmiKvp* retkvp = NULL;
   12916         OSCL_StackString<64> kvpparamkey;
   12917 
   12918         bool videoTrack = false;
   12919         bool audioTrack = false;
   12920         bool textTrack = false;
   12921         bool retVal = FindTrackForDatapathUsingMimeString(videoTrack, audioTrack, textTrack, aNodeContext.iEngineDatapath);
   12922         if (videoTrack && retVal)
   12923         {
   12924             // Video track
   12925             // Disable drop frame mode
   12926             kvpparamkey = _STRLIT_CHAR("x-pvmf/video/decoder/dropframe_enable;valtype=bool");
   12927             kvpparam.value.bool_value = false;
   12928         }
   12929         else if (audioTrack && retVal)
   12930         {
   12931             // Audio track
   12932             // Disable silence insertion
   12933             kvpparamkey = _STRLIT_CHAR("x-pvmf/audio/decoder/silenceinsertion_enable;valtype=bool");
   12934             kvpparam.value.bool_value = false;
   12935             aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginAudio.min), iSyncMarginAudio.max);
   12936         }
   12937 
   12938         if (kvpparamkey.get_size() > 0)
   12939         {
   12940             kvpparam.key = kvpparamkey.get_str();
   12941             aNodeContext.iEngineDatapath->iDecNodeCapConfigIF->setParametersSync(NULL, &kvpparam, 1, retkvp);
   12942             if (retkvp != NULL)
   12943             {
   12944                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Configuring dec node for player use via cap-config IF failed"));
   12945             }
   12946         }
   12947     }
   12948 
   12949     // Decrement the pending counter and go to next step if 0.
   12950     OSCL_ASSERT(aNodeContext.iEngineDatapath->iNumPendingCmd > 0);
   12951     --aNodeContext.iEngineDatapath->iNumPendingCmd;
   12952     if (aNodeContext.iEngineDatapath->iNumPendingCmd == 0)
   12953     {
   12954         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() All QueryInterface() commands complete"));
   12955 
   12956         // Prepare the datapath
   12957         PVMFStatus cmdstatus = DoDatapathPrepare(*(aNodeContext.iEngineDatapath), aNodeContext.iCmdId, aNodeContext.iCmdContext);
   12958 
   12959         if (cmdstatus != PVMFSuccess)
   12960         {
   12961             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12962                             (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Report command as failed, Add EH command"));
   12963             bool ehPending = CheckForPendingErrorHandlingCmd();
   12964             if (ehPending)
   12965             {
   12966                 // there should be no error handling queued.
   12967                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Already EH pending, should never happen"));
   12968                 return;
   12969             }
   12970             else
   12971             {
   12972                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   12973                 iCommandCompleteErrMsgInErrorHandling = NULL;
   12974                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   12975             }
   12976         }
   12977     }
   12978 
   12979     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Out"));
   12980 }
   12981 
   12982 
   12983 void PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   12984 {
   12985     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() In"));
   12986 
   12987     PVMFTimestamp requesttime = iTargetNPT;
   12988 
   12989     if (aNodeResp.GetCmdStatus() == PVMFErrNotSupported || aNodeResp.GetCmdStatus() == PVMFErrArgument)
   12990     {
   12991         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() QueryDataSourcePosition failed. Assume position goes to requested position"));
   12992     }
   12993     else if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   12994     {
   12995         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   12996                         (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() QueryDataSourcePosition failed, Add EH command"));
   12997         bool ehPending = CheckForPendingErrorHandlingCmd();
   12998         if (ehPending)
   12999         {
   13000             // there should be no error handling queued.
   13001             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePause() Already EH pending, should never happen"));
   13002             return;
   13003         }
   13004         PVMFErrorInfoMessageInterface* nextmsg = NULL;
   13005         if (aNodeResp.GetEventExtensionInterface())
   13006         {
   13007             nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   13008         }
   13009 
   13010         PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13011         iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   13012         iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   13013 
   13014         if (iState == PVP_ENGINE_STATE_PREPARING)
   13015             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   13016         else if (iState == PVP_ENGINE_STATE_RESUMING)
   13017             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   13018         return;
   13019     }
   13020     else
   13021     {
   13022         PVMFNodeCapability nodeCapability;
   13023         iSourceNode->GetCapability(nodeCapability);
   13024         PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
   13025         bool mpeg4FormatType = false;
   13026         if (formatType != NULL)
   13027         {
   13028             if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
   13029             {
   13030                 mpeg4FormatType = true;
   13031             }
   13032             else
   13033             {
   13034                 mpeg4FormatType = false;
   13035             }
   13036         }
   13037 
   13038         if (mpeg4FormatType)
   13039         {
   13040             // Every thing is OK.. Calculate the modified target position depending upon nearest before and after syncPoints.
   13041             // For MPEG4 files
   13042             CalculateActualPlaybackPosition();
   13043         }
   13044     }
   13045 
   13046     // Determine the SetDataSourcePosition parameter based on query result and reposition settings
   13047     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
   13048                     "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition()"
   13049                     "Requested NPT %d, Modified Target NPT %d", requesttime, iTargetNPT));
   13050 
   13051     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0,
   13052                     "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition()"
   13053                     "Requested NPT %d, Modified Target NPT %d", requesttime, iTargetNPT));
   13054 
   13055     uint32 startOfSeekWindow = 0;
   13056     if (requesttime > iSyncPointSeekWindow)
   13057     {
   13058         startOfSeekWindow = (requesttime - iSyncPointSeekWindow);
   13059     }
   13060     uint32 endOfSeekWindow = requesttime + iSyncPointSeekWindow;
   13061 
   13062     // 1) Check if the modified target position falls within the window
   13063     if ((iTargetNPT >= startOfSeekWindow) &&
   13064             (iTargetNPT <= endOfSeekWindow))
   13065     {
   13066         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
   13067                         "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
   13068                         "RequestedNPT(%d) ModifiedTargetNPT(%d) is in the window (%d, %d), Seeking To %d",
   13069                         requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, iTargetNPT));
   13070 
   13071         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0,
   13072                         "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
   13073                         "RequestedNPT(%d) ModifiedTargetNPT(%d) is in the window (%d, %d), Seeking To %d",
   13074                         requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, iTargetNPT));
   13075 
   13076         requesttime = iTargetNPT;
   13077     }
   13078     else
   13079     {
   13080         // 1) Check if the actual seek point is before the window start, then set the
   13081         // request time to start of the window
   13082         // 2) Check if the actual seek point is after the window end, then
   13083         // go back to start of the seek window
   13084         // SFR is not really an option here since we are not playing yet, therefore always
   13085         // go to start of the window
   13086         if ((iTargetNPT < startOfSeekWindow) ||
   13087                 (iTargetNPT > endOfSeekWindow))
   13088         {
   13089             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
   13090                             "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
   13091                             "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt False",
   13092                             requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
   13093 
   13094             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0,
   13095                             "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
   13096                             "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt False",
   13097                             requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
   13098 
   13099             requesttime = startOfSeekWindow;
   13100             iTargetNPT = requesttime;
   13101         }
   13102         else
   13103         {
   13104             //error
   13105             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0,
   13106                             "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
   13107                             "RequestedNPT(%d) ModifiedTargetNPT(%d) window (%d, %d), Error Condition Asserting",
   13108                             requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow));
   13109             OSCL_ASSERT(false);
   13110         }
   13111     }
   13112 
   13113     // Do the source positioning
   13114     PVMFStatus retval = DoSourceNodeSetDataSourcePosition(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13115     if (retval != PVMFSuccess)
   13116     {
   13117         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13118                         (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() Report command as failed, Add EH command"));
   13119         bool ehPending = CheckForPendingErrorHandlingCmd();
   13120         if (ehPending)
   13121         {
   13122             // there should be no error handling queued.
   13123             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() Already EH pending, should never happen"));
   13124             return;
   13125         }
   13126         else
   13127         {
   13128             iCommandCompleteStatusInErrorHandling = retval;
   13129             iCommandCompleteErrMsgInErrorHandling = NULL;
   13130             if (iState == PVP_ENGINE_STATE_PREPARING)
   13131                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   13132             else if (iState == PVP_ENGINE_STATE_RESUMING)
   13133                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   13134         }
   13135     }
   13136 
   13137     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() Out"));
   13138 }
   13139 
   13140 
   13141 void PVPlayerEngine::HandleSourceNodeSetDataSourcePosition(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   13142 {
   13143     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() In"));
   13144 
   13145     PVMFStatus cmdstatus = PVMFFailure;
   13146 
   13147     switch (aNodeResp.GetCmdStatus())
   13148     {
   13149         case PVMFErrArgument:
   13150         case PVMFErrNotSupported:
   13151         {
   13152             if (iChangePlaybackPositionWhenResuming)
   13153             {
   13154                 PVPPlaybackPosition curpos;
   13155                 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13156                 GetPlaybackClockPosition(curpos);
   13157                 uint32 clockcurpos = 0;
   13158                 bool tmpbool = false;
   13159                 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   13160 
   13161                 // since repositioning is not supported and if the playback position change request was
   13162                 // issued during paused state, then continue from paused position.
   13163                 iChangePlaybackPositionWhenResuming = false;
   13164                 iWatchDogTimerInterval = 0;
   13165                 iActualNPT = curpos.iPosValue.millisec_value;
   13166                 iActualMediaDataTS = clockcurpos;
   13167                 iSkipMediaDataTS = clockcurpos;
   13168 
   13169                 iStartNPT = iActualNPT;
   13170                 iStartMediaDataTS = iSkipMediaDataTS;
   13171 
   13172                 // also decrement the stream id as no skip will be called on MIO node.
   13173                 --iStreamID;
   13174 
   13175                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13176                 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
   13177                 SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
   13178                 infomsg->removeRef();
   13179             }
   13180             else
   13181             {
   13182                 // This happens when we are in preparing state
   13183                 // Since this repositioning was not supported, assume the playback
   13184                 // will start from time 0
   13185                 iWatchDogTimerInterval = 0;
   13186                 iActualNPT = 0;
   13187                 iActualMediaDataTS = 0;
   13188                 iSkipMediaDataTS = 0;
   13189                 // Then continue to handle like success case
   13190                 iStartNPT = 0;
   13191                 iStartMediaDataTS = 0;
   13192             }
   13193 
   13194             // Save the actual starting position for GetPlaybackRange() query
   13195             iTargetNPT = iActualNPT;
   13196             iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   13197             iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13198             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13199                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Requested begin position(%d ms) is not supported so start from prev location.",
   13200                              iTargetNPT));
   13201         }
   13202         break;
   13203 
   13204         case PVMFSuccess:
   13205         {
   13206             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13207                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() SetDataSourcePosition() successful. StartMediaTS %d ms, ActualNPT %d ms, TargetNPT %d ms",
   13208                              iActualMediaDataTS, iActualNPT, iTargetNPT));
   13209             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   13210                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() SetDataSourcePosition() successful. StartMediaTS %d ms, ActualNPT %d ms, TargetNPT %d ms",
   13211                              iActualMediaDataTS, iActualNPT, iTargetNPT));
   13212             // Compute the difference between actualNPT and targetNPT before any adjustments
   13213             if (iTargetNPT >= iActualNPT)
   13214             {
   13215                 iWatchDogTimerInterval = iTargetNPT - iActualNPT;
   13216             }
   13217 
   13218             // Determine if adjustment needed to skip to requested time
   13219             if (iSkipToRequestedPosition && (iActualNPT < iTargetNPT))
   13220             {
   13221                 if (iTargetNPT - iActualNPT > iNodeDataQueuingTimeout)
   13222                 {
   13223                     // Sync point seems to be far away in the stream
   13224                     // Can't adjust the skip time back so use the returned values to skip to
   13225                     iSkipMediaDataTS = iActualMediaDataTS;
   13226                     iTargetNPT = iActualNPT;
   13227                     iWatchDogTimerInterval = 0;
   13228                     iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   13229                 }
   13230                 else
   13231                 {
   13232                     //check if source node wants to override
   13233                     uint32 startNPTFrmSource = iActualNPT;
   13234                     if (iSourceNodePBCtrlIF->ComputeSkipTimeStamp(iTargetNPT,
   13235                             iActualNPT,
   13236                             iActualMediaDataTS,
   13237                             iSkipMediaDataTS,
   13238                             startNPTFrmSource) == PVMFSuccess)
   13239                     {
   13240                         iWatchDogTimerInterval = startNPTFrmSource - iActualNPT;
   13241                         iActualNPT = startNPTFrmSource;
   13242                         iTargetNPT = iActualNPT;
   13243                         iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   13244                     }
   13245                     else
   13246                     {
   13247                         // Adjust the media data time to skip-to to correspond to the requested time
   13248                         // Add the difference of target NPT with actual playback position in NPT to the actual media data time to get time to skip to.
   13249                         iSkipMediaDataTS = iActualMediaDataTS + (iTargetNPT - iActualNPT);
   13250                         iActualNPT = iTargetNPT;
   13251                     }
   13252                 }
   13253             }
   13254             else
   13255             {
   13256                 // Can't adjust the skip time back so use the returned values to skip to
   13257                 iSkipMediaDataTS = iActualMediaDataTS;
   13258                 iTargetNPT = iActualNPT;
   13259                 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   13260                 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13261                 iWatchDogTimerInterval = 0;
   13262             }
   13263 
   13264             // Save initial NTP and TS values
   13265             iStartNPT = iActualNPT;
   13266             iStartMediaDataTS = iSkipMediaDataTS;
   13267 
   13268             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13269                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() After adjustment StartMediaTS %d ms, AdjustedMediaTS %d ms, ActualPBPos %d ms Start NPT %d Start TS %d",
   13270                              iActualMediaDataTS, iSkipMediaDataTS, iActualNPT, iStartNPT, iStartMediaDataTS));
   13271             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   13272                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() After adjustment StartMediaTS %d ms, AdjustedMediaTS %d ms, ActualNPT %d ms StartNPT %d StartTS %d",
   13273                              iActualMediaDataTS, iSkipMediaDataTS, iActualNPT, iStartNPT, iStartMediaDataTS));
   13274         }
   13275         break;
   13276 
   13277         default:
   13278         {
   13279             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13280                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() failed, Add EH command"));
   13281             bool ehPending = CheckForPendingErrorHandlingCmd();
   13282             if (ehPending)
   13283             {
   13284                 // there should be no error handling queued.
   13285                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Already EH pending, should never happen"));
   13286                 return;
   13287             }
   13288             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   13289             if (aNodeResp.GetEventExtensionInterface())
   13290             {
   13291                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   13292             }
   13293 
   13294             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13295             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   13296             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   13297 
   13298             if (iState == PVP_ENGINE_STATE_PREPARING)
   13299                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   13300             else if (iState == PVP_ENGINE_STATE_RESUMING)
   13301                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   13302 
   13303             return;
   13304         }
   13305     }
   13306     // Repositioning so reset the EOS flag for each active datapath
   13307     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   13308     {
   13309         if (iDatapathList[i].iDatapath)
   13310         {
   13311             iDatapathList[i].iEndOfDataReceived = false;
   13312         }
   13313     }
   13314 
   13315     // Contine on and start the source node
   13316     cmdstatus = DoSourceNodeStart(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13317     if (cmdstatus != PVMFSuccess)
   13318     {
   13319         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Report command as failed, Add EH command"));
   13320         bool ehPending = CheckForPendingErrorHandlingCmd();
   13321         if (ehPending)
   13322         {
   13323             // there should be no error handling queued.
   13324             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Already EH pending, should never happen"));
   13325             return;
   13326         }
   13327         else
   13328         {
   13329             iCommandCompleteStatusInErrorHandling = cmdstatus;
   13330             iCommandCompleteErrMsgInErrorHandling = NULL;
   13331             if (iState == PVP_ENGINE_STATE_PREPARING)
   13332                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   13333             else if (iState == PVP_ENGINE_STATE_RESUMING)
   13334                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   13335         }
   13336     }
   13337 
   13338     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Out"));
   13339 }
   13340 
   13341 void PVPlayerEngine::HandleSourceNodeSetDataSourceDirection(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   13342 {
   13343     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() In"));
   13344 
   13345     if (iChangePlaybackDirectionWhenResuming)
   13346     {
   13347         // Continuation of Engine Resume sequence.
   13348 
   13349         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Context RESUME"));
   13350         PVMFStatus cmdstatus = PVMFFailure;
   13351 
   13352         switch (aNodeResp.GetCmdStatus())
   13353         {
   13354             case PVMFErrArgument:
   13355             case PVMFErrNotSupported:
   13356             {
   13357                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13358                                 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Requested direction is not supported!"));
   13359                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13360                 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
   13361                 SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
   13362                 infomsg->removeRef();
   13363             }
   13364             break;
   13365 
   13366             case PVMFSuccess:
   13367             {
   13368                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13369                                 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() SetDataSourceDirection() successful. StartMediaTS %d ms, ActualPBPos %d ms",
   13370                                  iActualMediaDataTS, iActualNPT));
   13371 
   13372                 //there's no adjustment to the media TS here.
   13373                 iSkipMediaDataTS = iActualMediaDataTS;
   13374                 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   13375                 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13376 
   13377                 //Install the new direction and get the repositioning target.
   13378                 UpdateDirection(iActualNPT, iSkipMediaDataTS, iChangeDirectionNPT);
   13379 
   13380                 //Reposition the source to the desired playback time
   13381                 if (!iChangeDirectionNPT.iIndeterminate)
   13382                 {
   13383                     iChangePlaybackDirectionWhenResuming = false;
   13384                     iChangePlaybackPositionWhenResuming = true;
   13385                     PVPlayerEngineCommand cmd(0, aNodeContext.iCmdId, aNodeContext.iCmdContext, NULL, false);
   13386                     iCurrentBeginPosition = iChangeDirectionNPT;
   13387                     PVMFStatus retval = UpdateCurrentBeginPosition(iCurrentBeginPosition, cmd);
   13388                     if (retval == PVMFPending)
   13389                     {
   13390                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Repos to %d started", iChangeDirectionNPT.iPosValue));
   13391                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
   13392                         return;//wait on the repos sequence...
   13393                     }
   13394                     else if (retval != PVMFSuccess)
   13395                     {
   13396                         //else can't reposition, ignore failure and continue.
   13397                         iChangeDirectionNPT.iIndeterminate = true;
   13398                         iChangePlaybackPositionWhenResuming = false;
   13399                         //need to leave the flag set for later in HandleDatapathResume,
   13400                         //to trigger the skip media data.
   13401                         iChangePlaybackDirectionWhenResuming = true;
   13402                     }
   13403                 }
   13404             }
   13405             break;
   13406 
   13407             default:
   13408             {
   13409                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13410                                 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() failed, Add EH command"));
   13411                 bool ehPending = CheckForPendingErrorHandlingCmd();
   13412                 if (ehPending)
   13413                 {
   13414                     // there should be no error handling queued.
   13415                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Already EH pending, should never happen"));
   13416                     return;
   13417                 }
   13418                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   13419                 if (aNodeResp.GetEventExtensionInterface())
   13420                 {
   13421                     nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   13422                 }
   13423 
   13424                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13425                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   13426                 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   13427                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   13428                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
   13429                 return;
   13430             }
   13431         }
   13432 
   13433 
   13434         // Repositioning so reset the EOS flag for each active datapath
   13435         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   13436         {
   13437             if (iDatapathList[i].iDatapath)
   13438             {
   13439                 iDatapathList[i].iEndOfDataReceived = false;
   13440             }
   13441         }
   13442 
   13443         // Start the source node.
   13444         cmdstatus = DoSourceNodeStart(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13445         if (cmdstatus != PVMFSuccess)
   13446         {
   13447             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13448                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Report command as failed, Add EH command"));
   13449             bool ehPending = CheckForPendingErrorHandlingCmd();
   13450             if (ehPending)
   13451             {
   13452                 // there should be no error handling queued.
   13453                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Already EH pending, should never happen"));
   13454                 return;
   13455             }
   13456             else
   13457             {
   13458                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   13459                 iCommandCompleteErrMsgInErrorHandling = NULL;
   13460                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   13461             }
   13462         }
   13463     }
   13464     else
   13465     {
   13466         //Continuation of SetPlaybackRate sequence.
   13467 
   13468         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Context SETPLAYBACKRATE"));
   13469 
   13470         if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   13471         {
   13472             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() SetDataSourceDirection failed. Playback position change has been cancelled"));
   13473 
   13474             if (aNodeResp.GetCmdStatus() == PVMFErrNotSupported || aNodeResp.GetCmdStatus() == PVMFErrArgument)
   13475             {
   13476                 // For non-fatal error, continue playback by resuming the clock
   13477                 StartPlaybackClock();
   13478             }
   13479             else
   13480             {
   13481                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13482                                 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() failed, Add EH command"));
   13483                 // Initiate error handling
   13484                 bool ehPending = CheckForPendingErrorHandlingCmd();
   13485                 if (ehPending)
   13486                 {
   13487                     // there should be no error handling queued.
   13488                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Already EH pending, should never happen"));
   13489                     return;
   13490                 }
   13491                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   13492                 if (aNodeResp.GetEventExtensionInterface())
   13493                 {
   13494                     nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   13495                 }
   13496 
   13497                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13498                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   13499                 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   13500                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE, NULL, NULL, NULL, false);
   13501                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
   13502                 return;
   13503             }
   13504 
   13505             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   13506             if (aNodeResp.GetEventExtensionInterface() != NULL)
   13507             {
   13508                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   13509             }
   13510             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13511             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
   13512 
   13513             // Complete the SetPlaybackRate() command as failed
   13514             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, aNodeResp.GetCmdStatus(), OSCL_STATIC_CAST(PVInterface*, errmsg));
   13515 
   13516             errmsg->removeRef();
   13517             errmsg = NULL;
   13518             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
   13519             return;
   13520         }
   13521 
   13522         // no adjustement here.
   13523         iSkipMediaDataTS = iActualMediaDataTS;
   13524         iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   13525         iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13526 
   13527         //Install the new direction and get the repositioning target
   13528         UpdateDirection(iActualNPT, iSkipMediaDataTS, iChangeDirectionNPT);
   13529 
   13530         //Launch a repositioning sequence now.
   13531         if (!iChangeDirectionNPT.iIndeterminate)
   13532         {
   13533             PVPlayerEngineCommand cmd(0, aNodeContext.iCmdId, aNodeContext.iCmdContext, NULL, false);
   13534             iCurrentBeginPosition = iChangeDirectionNPT;
   13535             PVMFStatus retval = UpdateCurrentBeginPosition(iCurrentBeginPosition, cmd);
   13536             if (retval == PVMFPending)
   13537             {
   13538                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Repos to %d started", iChangeDirectionNPT.iPosValue));
   13539                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
   13540                 return;//wait on the repos sequence...
   13541             }
   13542             else if (retval != PVMFSuccess)
   13543             {
   13544                 //the direction is already changed, so just ignore this failure and continue
   13545                 iChangeDirectionNPT.iIndeterminate = true;
   13546             }
   13547         }
   13548 
   13549         // Repositioning so reset the EOS flag for each active datapath
   13550         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   13551         {
   13552             if (iDatapathList[i].iDatapath)
   13553             {
   13554                 iDatapathList[i].iEndOfDataReceived = false;
   13555             }
   13556         }
   13557 
   13558         // Skip to the new source node position, so that all the data that was queued
   13559         // when the command was received will get flushed.
   13560 
   13561         PVMFStatus retval = DoSinkNodeSkipMediaDataDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13562         if (retval != PVMFSuccess)
   13563         {
   13564             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Skipping media data request in sink nodes failed. Repositioning did not complete."));
   13565             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13566             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSink, puuid, NULL));
   13567 
   13568             //clear the pending direction change NPT.
   13569             iChangeDirectionNPT.iIndeterminate = true;
   13570 
   13571             // Complete the SetPlaybackRate() command as failed
   13572             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval, OSCL_STATIC_CAST(PVInterface*, errmsg));
   13573 
   13574             errmsg->removeRef();
   13575             errmsg = NULL;
   13576         }
   13577         // else wait on HandleSinkNodeSkipMediaDataDuringPlayback.
   13578     }
   13579     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
   13580 }
   13581 
   13582 void PVPlayerEngine::HandleSourceNodeStart(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   13583 {
   13584     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   13585                     (0, "PVPlayerEngine::HandleSourceNodeStart() Tick=%d", OsclTickCount::TickCount()));
   13586 
   13587     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStart() In"));
   13588 
   13589     PVMFStatus cmdstatus = PVMFErrNotSupported;
   13590 
   13591     switch (aNodeResp.GetCmdStatus())
   13592     {
   13593         case PVMFSuccess:
   13594         {
   13595             // Issue Skip on Sink Node and Start on datapaths back to back. This is done to make sure that
   13596             // sink node is started only after discarding the data from an earlier stream.
   13597             cmdstatus = DoSinkNodeSkipMediaData(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13598             if (cmdstatus != PVMFSuccess)
   13599             {
   13600                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStart() Skip of sink node did a leave, asserting"));
   13601                 OSCL_ASSERT(false);
   13602             }
   13603 
   13604             // Start the available datapaths
   13605             iNumPendingDatapathCmd = 0;
   13606             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   13607             {
   13608                 if (iDatapathList[i].iDatapath)
   13609                 {
   13610                     PVMFStatus retval = DoDatapathStart(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13611                     if (retval == PVMFSuccess)
   13612                     {
   13613                         ++iNumPendingDatapathCmd;
   13614                         cmdstatus = PVMFSuccess;
   13615                     }
   13616                     else
   13617                     {
   13618                         cmdstatus = retval;
   13619                         break;
   13620                     }
   13621                 }
   13622             }
   13623             if (iNumPendingDatapathCmd == 0)
   13624             {
   13625                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13626                                 (0, "PVPlayerEngine:HandleSourceNodeStart() DoDatapathStart failed, Add EH command"));
   13627                 bool ehPending = CheckForPendingErrorHandlingCmd();
   13628                 if (ehPending)
   13629                 {
   13630                     // there should be no error handling queued.
   13631                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine:HandleSourceNodeStart() Already EH pending, should never happen"));
   13632                     return;
   13633                 }
   13634                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   13635                 iCommandCompleteErrMsgInErrorHandling = NULL;
   13636                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   13637             }
   13638         }
   13639         break;
   13640 
   13641         default:
   13642         {
   13643             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   13644                             (0, "PVPlayerEngine:HandleSourceNodeStart() failed, Add EH command"));
   13645             bool ehPending = CheckForPendingErrorHandlingCmd();
   13646             if (ehPending)
   13647             {
   13648                 // there should be no error handling queued.
   13649                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine:HandleSourceNodeStart() Already EH pending, should never happen"));
   13650                 return;
   13651             }
   13652             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   13653             if (aNodeResp.GetEventExtensionInterface())
   13654             {
   13655                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   13656             }
   13657 
   13658             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13659             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   13660             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   13661             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   13662         }
   13663         break;
   13664     }
   13665 
   13666     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStart() Out"));
   13667 }
   13668 
   13669 
   13670 void PVPlayerEngine::HandleSinkNodeSkipMediaData(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   13671 {
   13672     OSCL_UNUSED_ARG(aNodeContext);
   13673     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   13674                     (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() for %s Tick=%d",
   13675                      aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   13676 
   13677     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   13678                     (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() for %s, iNumPVMFInfoStartOfDataPending=%d",
   13679                      aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), iNumPVMFInfoStartOfDataPending));
   13680 
   13681     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13682                     (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() In"));
   13683 
   13684     --iNumPendingNodeCmd;
   13685 
   13686     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   13687     {
   13688         // Sink node report error with SkipMediaData()
   13689         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() Sink node report error for SkipMediaData(). Asserting"));
   13690         OSCL_ASSERT(false);
   13691     }
   13692 
   13693     --iNumPendingSkipCompleteEvent;
   13694 
   13695     if (iNumPendingNodeCmd == 0)
   13696     {
   13697         // We dont start the playback clock here since engine is waiting for Start on Sink nodes to complete
   13698         // This will also check the order in which Sink Node completes the command. Sinks should complete Skip
   13699         // first and then Start, therefore iNumPendingDatapathCmd should always be greater than zero when
   13700         // this happens. If not just assert.
   13701         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   13702                         (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() Skip Complete"));
   13703     }
   13704 
   13705     if ((iNumPendingSkipCompleteEvent == 0) && (iNumPVMFInfoStartOfDataPending == 0))
   13706     {
   13707         // we have received all the bos event so cancel the watchDogTimer if any.
   13708         if (iWatchDogTimer->IsBusy())
   13709         {
   13710             iWatchDogTimer->Cancel();
   13711             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData - WatchDogTimer cancelled"));
   13712         }
   13713     }
   13714 
   13715     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() Out"));
   13716 }
   13717 
   13718 
   13719 void PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   13720 {
   13721     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() In"));
   13722 
   13723     PVMFTimestamp requesttime = iTargetNPT;
   13724     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   13725     {
   13726         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() QueryDataSourcePosition failed. Assume position goes to requested position"));
   13727     }
   13728     else
   13729     {
   13730         PVMFNodeCapability nodeCapability;
   13731         iSourceNode->GetCapability(nodeCapability);
   13732         PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
   13733         bool mpeg4FormatType = false;
   13734         if (formatType != NULL)
   13735         {
   13736             if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
   13737             {
   13738                 mpeg4FormatType = true;
   13739             }
   13740             else
   13741             {
   13742                 mpeg4FormatType = false;
   13743             }
   13744         }
   13745         if (mpeg4FormatType)
   13746         {
   13747             // Every thing is OK.. Calculate the modified target position depending upon nearest before and after syncPoints.
   13748             // For MPEG4 files
   13749             CalculateActualPlaybackPosition();
   13750         }
   13751     }
   13752 
   13753     // Determine the SetDataSourcePosition parameter based on query result and reposition settings
   13754     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
   13755                     "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback()"
   13756                     "Requested NPT %d, ModifiedTarget NPT %d", requesttime, iTargetNPT));
   13757 
   13758     uint32 startOfSeekWindow = 0;
   13759     if (requesttime > iSyncPointSeekWindow)
   13760     {
   13761         startOfSeekWindow = (requesttime - iSyncPointSeekWindow);
   13762     }
   13763     uint32 endOfSeekWindow = requesttime + iSyncPointSeekWindow;
   13764 
   13765     PVPPlaybackPosition curpos;
   13766     curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13767     GetPlaybackClockPosition(curpos);
   13768     bool oSFR = false;
   13769 
   13770     //depending on whether it is fwd or rwnd, the window is different
   13771     //if doing a rwnd, the worst case window is (0, currentplaybackposition)
   13772     //if doing a fwd, the worst case window is (currentplaybackposition, endofclip)
   13773     if (requesttime <= curpos.iPosValue.millisec_value)
   13774     {
   13775         //requested pos <= currpos => rwnd
   13776         //cap end of seek window to be the current play back pos
   13777         endOfSeekWindow = curpos.iPosValue.millisec_value;
   13778     }
   13779     if (requesttime > curpos.iPosValue.millisec_value)
   13780     {
   13781         //requested pos > currpos => fwd
   13782         //cap start of seek window to be the current play back pos
   13783         startOfSeekWindow = curpos.iPosValue.millisec_value;
   13784     }
   13785 
   13786     // 1) Check if the Modified target position falls within the window
   13787     if ((iTargetNPT >= startOfSeekWindow) &&
   13788             (iTargetNPT <= endOfSeekWindow))
   13789     {
   13790         // Check for SFR
   13791         // In case if actual playback position
   13792         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
   13793                         "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
   13794                         "RequestedNPT(%d) ModifiedTargetNPT(%d) is in the window (%d, %d), Seeking To %d",
   13795                         requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, iTargetNPT));
   13796 
   13797         requesttime = iTargetNPT;
   13798     }
   13799     else
   13800     {
   13801         // Check for SFR
   13802         // SFR means currplaybackpos < requestedpos
   13803         if (curpos.iPosValue.millisec_value < requesttime)
   13804         {
   13805             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
   13806                             "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
   13807                             "CurrNPT(%d) less than RequestedNPT(%d) Ignoring ModifiedTargetNPT(%d) and the window (%d, %d), Doing SFR",
   13808                             curpos.iPosValue.millisec_value, requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
   13809 
   13810             oSFR = true;
   13811 
   13812             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13813             PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoAttemptingSFRAsPartOfSetPlayBackRange, puuid, NULL));
   13814             SendInformationalEvent(PVMFInfoPositionStatus, OSCL_STATIC_CAST(PVInterface*, infomsg));
   13815             infomsg->removeRef();
   13816 
   13817         }
   13818         else
   13819         {
   13820             // if the actual seek point is before the window start,
   13821             // or if the actual seek point is after the window end,
   13822             // then go back to start of the seek window only in case of a finite window
   13823             // in case of infinite window just go to the requested position and do normal
   13824             // repositioning
   13825             if (iSyncPointSeekWindow == 0x7FFFFFFF)
   13826             {
   13827                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
   13828                                 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
   13829                                 "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt True",
   13830                                 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
   13831 
   13832                 iTargetNPT = requesttime;
   13833             }
   13834             else
   13835             {
   13836                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
   13837                                 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
   13838                                 "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt False",
   13839                                 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
   13840 
   13841                 requesttime = startOfSeekWindow;
   13842                 iTargetNPT = requesttime;
   13843             }
   13844         }
   13845     }
   13846 
   13847     if (oSFR)
   13848     {
   13849         // No need to change source position so go to skipping at sink nodes
   13850         // First determine to what time sink nodes should skip to
   13851         // Get current playback clock position in media data time
   13852         uint32 clockcurpos = 0;
   13853         bool tmpbool = false;
   13854         iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   13855 
   13856         // for SFR since the source node is bypassed, there will be no frames generated with new
   13857         // Stream ID so, for skip to complete on Sink Node, Stream ID needs to be decremented. As
   13858         // there will be no new Stream in case of SFR.
   13859         --iStreamID;
   13860 
   13861         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13862                         (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() New source reposition before current position so no need to change source position."));
   13863 
   13864         if (iSkipToRequestedPosition)
   13865         {
   13866             // Skip to the requested begin position
   13867             // Add the difference of target NPT with current time in NPT to the current clock to get media data time to skip to.
   13868             iActualMediaDataTS = clockcurpos;
   13869             iSkipMediaDataTS = (requesttime - curpos.iPosValue.millisec_value) + clockcurpos;
   13870             iActualNPT = requesttime;
   13871             iWatchDogTimerInterval = requesttime - curpos.iPosValue.millisec_value;
   13872 
   13873             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13874                             (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Skip-to-requested position SET. ActualNPT=%d, ActualMediaTS=%d, AdjustedMediaTS=%d",
   13875                              iActualNPT, iActualMediaDataTS, iSkipMediaDataTS));
   13876         }
   13877         else
   13878         {
   13879             // Just continue playback from current position
   13880             iActualMediaDataTS = clockcurpos;
   13881             iSkipMediaDataTS = clockcurpos;
   13882             iActualNPT = curpos.iPosValue.millisec_value;
   13883             iWatchDogTimerInterval = 0;
   13884 
   13885             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   13886                             (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Skip-to-requested position NOT SET so continue playing. ActualNPT=%d, ActualMediaTS=%d, AdjustedMediaTS=%d",
   13887                              iActualNPT, iActualMediaDataTS, iSkipMediaDataTS));
   13888         }
   13889 
   13890         PVMFStatus retval = DoSinkNodeSkipMediaDataDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext, true);
   13891         if (retval != PVMFSuccess)
   13892         {
   13893             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Skipping media data request in sink nodes failed. Repositioning did not complete."));
   13894             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13895             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSink, puuid, NULL));
   13896 
   13897             //clear the pending direction change NPT.
   13898             iChangeDirectionNPT.iIndeterminate = true;
   13899 
   13900             // Complete the SetPlaybackRange() command as failed
   13901             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval, OSCL_STATIC_CAST(PVInterface*, errmsg));
   13902 
   13903             errmsg->removeRef();
   13904             errmsg = NULL;
   13905         }
   13906 
   13907     }
   13908     else
   13909     {
   13910         // Do the source positioning
   13911         PVMFStatus retval = DoSourceNodeSetDataSourcePositionDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   13912         if (retval != PVMFSuccess)
   13913         {
   13914             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() SetDataSourcePosition failed. Playback position change has been cancelled"));
   13915             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   13916             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, NULL));
   13917 
   13918             // Complete the SetPlaybackRange() command as failed
   13919             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval, OSCL_STATIC_CAST(PVInterface*, errmsg));
   13920 
   13921             errmsg->removeRef();
   13922             errmsg = NULL;
   13923         }
   13924     }
   13925 
   13926     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Out"));
   13927 }
   13928 
   13929 void PVPlayerEngine::CalculateActualPlaybackPosition()
   13930 {
   13931     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition In"));
   13932 
   13933     PVPPlaybackPosition curpos;
   13934     curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   13935     GetPlaybackClockPosition(curpos);
   13936 
   13937     // Following code has been taken from MP4 parser node, all the vars are kept very near to the MP4 parser node.
   13938     // Previously the calculation of before and after sync point was done in MP4 parser node.
   13939 
   13940     if (curpos.iPosValue.millisec_value > iTargetNPT)
   13941     {
   13942         // curpos.iPosValue.millisec_value was passed as iActualNPT in QueryDataSourcePosition
   13943         // which became aActualNPT while collection, and used to decide forward and reverse repos.
   13944         iBackwardReposFlag = true;
   13945         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition In: Backward Reposition"));
   13946     }
   13947     else
   13948     {
   13949         iForwardReposFlag = true;
   13950         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition In: Forward Reposition"));
   13951     }
   13952 
   13953     // pick the closest time to targetNPT
   13954     uint32 delta = 0;
   13955     uint32 diffBetSeekPointBeforeAndTarget = 0;
   13956     if (PVTimeComparisonUtils::IsEarlier(iSeekPointBeforeTargetNPT, iTargetNPT, delta))
   13957     {
   13958         // this should always be true when checking the SeekPointBefore with
   13959         // targetNPT.
   13960         diffBetSeekPointBeforeAndTarget = delta;
   13961         delta = 0;
   13962     }
   13963     else
   13964     {
   13965         // this will only happen when mp4ff library returns an SeekPointBefore which
   13966         // is after targetNPT with small delta because of some rounding off error in
   13967         // media clock converter class.
   13968         diffBetSeekPointBeforeAndTarget = delta;
   13969         delta = 0;
   13970     }
   13971 
   13972     uint32 diffBetSeekPointAfterAndTarget = 0;
   13973     if (PVTimeComparisonUtils::IsEarlier(iTargetNPT, iSeekPointAfterTargetNPT, delta))
   13974     {
   13975         // this should always be true when checking the SeekPointAfter with
   13976         // targetNPT.
   13977         diffBetSeekPointAfterAndTarget = delta;
   13978         delta = 0;
   13979     }
   13980     else
   13981     {
   13982         // this should never happen.
   13983         diffBetSeekPointAfterAndTarget = delta;
   13984         delta = 0;
   13985     }
   13986 
   13987     // modify the target NPT and set it to the closest I-frame returned by parser node.
   13988     if (diffBetSeekPointAfterAndTarget < diffBetSeekPointBeforeAndTarget)
   13989     {
   13990         iTargetNPT = iSeekPointAfterTargetNPT;
   13991     }
   13992     else
   13993     {
   13994         if (iSeekPointBeforeTargetNPT < curpos.iPosValue.millisec_value && iForwardReposFlag)
   13995         {
   13996             iTargetNPT = iSeekPointAfterTargetNPT;
   13997             iForwardReposFlag = false;
   13998         }
   13999         else
   14000         {
   14001             iTargetNPT = iSeekPointBeforeTargetNPT;
   14002             iForwardReposFlag = false;
   14003         }
   14004     }
   14005     if (iBackwardReposFlag) // To avoid backwardlooping :: A flag to remember backward repositioning
   14006     {
   14007         iTargetNPT = iSeekPointBeforeTargetNPT;
   14008         iBackwardReposFlag = false;
   14009     }
   14010 
   14011 
   14012     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
   14013                     "PVPlayerEngine::CalculateActualPlaybackPosition()"
   14014                     "targetNPT %d Current NPT %d, Modified Target NPT %d, SeekPointBeforeTargetNPT %d, SeekPointAfterTargetNPT %d ",
   14015                     iCurrentBeginPosition.iPosValue.millisec_value, curpos.iPosValue.millisec_value, iTargetNPT, iSeekPointBeforeTargetNPT, iSeekPointAfterTargetNPT));
   14016 
   14017     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition Out"));
   14018 }
   14019 
   14020 void PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14021 {
   14022     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() In"));
   14023 
   14024     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   14025     {
   14026         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition failed. Playback position change has been cancelled"));
   14027 
   14028         if (aNodeResp.GetCmdStatus() == PVMFErrNotSupported || aNodeResp.GetCmdStatus() == PVMFErrArgument)
   14029         {
   14030             PVPPlaybackPosition curpos;
   14031             curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   14032             GetPlaybackClockPosition(curpos);
   14033             uint32 clockcurpos = 0;
   14034             bool tmpbool = false;
   14035             iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   14036 
   14037             // since repositioning is not supported continue playing from current position.
   14038             iWatchDogTimerInterval = 0;
   14039             iActualNPT = curpos.iPosValue.millisec_value;
   14040             iActualMediaDataTS = clockcurpos;
   14041             iSkipMediaDataTS = clockcurpos;
   14042 
   14043             iStartNPT = iActualNPT;
   14044             iStartMediaDataTS = iSkipMediaDataTS;
   14045 
   14046             // also decrement the stream id as no skip will be called on MIO node.
   14047             --iStreamID;
   14048 
   14049             // For non-fatal error, continue playback by resuming the clock
   14050             StartPlaybackClock();
   14051             // Complete the SetPlaybackRange() command as notsupported / failed
   14052             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, aNodeResp.GetCmdStatus());
   14053         }
   14054         else
   14055         {
   14056             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14057                             (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() failed, Add EH command"));
   14058             bool ehPending = CheckForPendingErrorHandlingCmd();
   14059             if (ehPending)
   14060             {
   14061                 // there should be no error handling queued.
   14062                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14063                                 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() Already EH pending, should never happen"));
   14064                 return;
   14065             }
   14066             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14067             if (aNodeResp.GetEventExtensionInterface())
   14068             {
   14069                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14070             }
   14071 
   14072             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14073             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   14074             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   14075             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE, NULL, NULL, NULL, false);
   14076         }
   14077         return;
   14078     }
   14079 
   14080     if ((iCurrentBeginPosition.iMode != PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT) &&
   14081             (iCurrentBeginPosition.iMode != PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION))
   14082     {
   14083         if (iCurrentBeginPosition.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
   14084         {
   14085             iActualMediaDataTS = iDataSourcePosParams.iActualMediaDataTS;
   14086             iActualNPT = iDataSourcePosParams.iActualNPT;
   14087         }
   14088 
   14089         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   14090                         (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition() successful. StartMediaTS %d ms, ActualPBPos %d ms",
   14091                          iActualMediaDataTS, iActualNPT));
   14092 
   14093         if (iCurrentBeginPosition.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
   14094         {
   14095             if (iTargetNPT >= iActualNPT)
   14096             {
   14097                 iWatchDogTimerInterval = iTargetNPT - iActualNPT;
   14098             }
   14099         }
   14100         // Compute the difference between actualNPT and targetNPT before any adjustments
   14101         else if (iTargetNPT >= iActualNPT)
   14102         {
   14103             iWatchDogTimerInterval = iTargetNPT - iActualNPT;
   14104         }
   14105 
   14106         //iCurrentBeginPosition.iPosUnit has served its purpose, it is ok if it is overwritten
   14107         if (iSkipToRequestedPosition && (iActualNPT < iTargetNPT))
   14108         {
   14109             if (iTargetNPT - iActualNPT >= iNodeDataQueuingTimeout)
   14110             {
   14111                 // Can't adjust the skip time back so use the returned values to skip to
   14112                 iSkipMediaDataTS = iActualMediaDataTS;
   14113                 iTargetNPT = iActualNPT;
   14114                 iWatchDogTimerInterval = 0;
   14115             }
   14116             else
   14117             {
   14118                 //check if source node wants to override
   14119                 uint32 startNPTFrmSource = iActualNPT;
   14120                 if (iSourceNodePBCtrlIF->ComputeSkipTimeStamp(iTargetNPT,
   14121                         iActualNPT,
   14122                         iActualMediaDataTS,
   14123                         iSkipMediaDataTS,
   14124                         startNPTFrmSource) == PVMFSuccess)
   14125                 {
   14126                     iWatchDogTimerInterval = startNPTFrmSource - iActualNPT;
   14127                     iActualNPT = startNPTFrmSource;
   14128                 }
   14129                 else
   14130                 {
   14131                     // Adjust the media data time to skip-to to correspond to the requested time
   14132                     // Add the difference of target NPT with actual playback position in NPT to the actual media data time to get time to skip to.
   14133                     iSkipMediaDataTS = iActualMediaDataTS + (iTargetNPT - iActualNPT);
   14134                     // Set the actual playback position to the requested time since actual media data TS was adjusted
   14135                     // This is important since the difference between the two is used to calculate the NPT to media data offset in HandleSinkNodeskipMediaDataDuringPlayback()
   14136                     iActualNPT = iTargetNPT;
   14137                 }
   14138 
   14139             }
   14140             iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   14141         }
   14142         else
   14143         {
   14144             // Can't adjust the skip time back so just use the returned values to skip to
   14145             iSkipMediaDataTS = iActualMediaDataTS;
   14146             iTargetNPT = iActualNPT;
   14147             iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
   14148             iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   14149             iWatchDogTimerInterval = 0;
   14150         }
   14151 
   14152         uint32 clockcurpos = 0;
   14153         bool tmpbool;
   14154         // Get current playback clock position
   14155         iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
   14156 
   14157         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   14158                         (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() After adjustment StartMediaTS %d ms, AdjustedMediaTS %d ms, ActualPBPos %d ms Clock %d ms",
   14159                          iActualMediaDataTS, iSkipMediaDataTS, iActualNPT, clockcurpos));
   14160 
   14161         // Repositioning so reset the EOS flag for each active datapath
   14162         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   14163         {
   14164             if (iDatapathList[i].iDatapath)
   14165             {
   14166                 iDatapathList[i].iEndOfDataReceived = false;
   14167             }
   14168         }
   14169 
   14170         PVMFStatus retval = DoSinkNodeSkipMediaDataDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   14171         if (retval != PVMFSuccess)
   14172         {
   14173             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() Skipping media data request in sink nodes failed. Repositioning did not complete."));
   14174 
   14175             // clear the pending direction change NPT.
   14176             iChangeDirectionNPT.iIndeterminate = true;
   14177 
   14178             // Complete the SetPlaybackRange() command as failed
   14179             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval);
   14180         }
   14181     }
   14182     else
   14183     {
   14184         PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14185         if (aNodeResp.GetEventExtensionInterface() != NULL)
   14186         {
   14187             nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14188         }
   14189         PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14190         PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
   14191 
   14192         // Complete the SetPlaybackRange() command as Success
   14193         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, aNodeResp.GetCmdStatus(), OSCL_STATIC_CAST(PVInterface*, errmsg));
   14194         if (errmsg)
   14195         {
   14196             errmsg->removeRef();
   14197             errmsg = NULL;
   14198         }
   14199     }
   14200     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() Out"));
   14201 }
   14202 
   14203 void PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14204 {
   14205     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   14206                     (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() for %s Tick=%d",
   14207                      aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   14208 
   14209     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   14210                     (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() for %s, iNumPVMFInfoStartOfDataPending=%d",
   14211                      aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), iNumPVMFInfoStartOfDataPending));
   14212 
   14213     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   14214     {
   14215         // Sink node report error with SkipMediaData()
   14216         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Sink node report error for SkipMediaData(). Asserting"));
   14217         OSCL_ASSERT(false);
   14218     }
   14219 
   14220     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   14221 
   14222     // Stop the sink that has reached the skipping end point until other sinks are ready
   14223     if (aNodeContext.iEngineDatapath->iDatapath && aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF)
   14224     {
   14225         aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->ClockStopped();
   14226     }
   14227     else
   14228     {
   14229         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Datapath does not exist or sync control IF not available."));
   14230     }
   14231 
   14232     --iNumPendingSkipCompleteEvent;
   14233 
   14234     --iNumPendingNodeCmd;
   14235 
   14236     if (iNumPendingNodeCmd == 0)
   14237     {
   14238         // Set the clock to the specified begin time just before Start of playback Clock
   14239         iPlaybackClock.Stop();
   14240         bool overflow = 0;
   14241         iPlaybackClock.SetStartTime32(iSkipMediaDataTS, PVMF_MEDIA_CLOCK_MSEC, overflow);
   14242 
   14243         if (iOverflowFlag)
   14244         {
   14245             iOverflowFlag = false;
   14246             iActualNPT = iSkipMediaDataTS;
   14247         }
   14248         if ((iNumPVMFInfoStartOfDataPending == 0) &&
   14249                 (iState == PVP_ENGINE_STATE_STARTED))
   14250         {
   14251             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   14252                             (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Skipping WatchDogTimer - Starting PlayBackClock"));
   14253             StartPlaybackClock();
   14254         }
   14255         else
   14256         {
   14257             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   14258                             (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Setting WatchDogTimer for %d ms, TargetNPT=%d  ActualNPT=%d, if interval zero set to default 1 second",
   14259                              iWatchDogTimerInterval, iTargetNPT, iActualNPT));
   14260             // There can be a case in which WatchDogTimerInterval is zero and iNumPVMFInfoStartOfDataPending is greater than zero.
   14261             // In this case it is possible InfoStartofData is not sent by Sink Nodes for some time and player hangs. To avoid the player hang
   14262             // set the watchdog timer Interval to the default value of 1 second. If interval is 0, it will be set to default 1 second.
   14263             iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
   14264             iWatchDogTimer->Start();
   14265         }
   14266 
   14267         // Set the actual playback position to the requested time since actual media data TS was adjusted
   14268         // This is important since the difference between the two is used to calculate the NPT to media data offset
   14269         // This is not required here as the ActualPlaybackPosition is already adjusted before calling Skip on Sink Node.
   14270         // iActualNPT=iCurrentBeginPosition.iPosValue.millisec_value;
   14271 
   14272         //clear the pending direction change NPT.
   14273         iChangeDirectionNPT.iIndeterminate = true;
   14274         // Save the start NPT and TS
   14275         iStartNPT = iActualNPT;
   14276         iStartMediaDataTS = iSkipMediaDataTS;
   14277         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO,
   14278                         (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() TargetNPT %d, ActualNPT %d StartTS %d",
   14279                          iTargetNPT, iStartNPT, iStartMediaDataTS));
   14280         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   14281                         (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() TargetNPT %d, ActualNPT %d StartTS %d",
   14282                          iTargetNPT, iStartNPT, iStartMediaDataTS));
   14283 
   14284         // Send event to the observer indicating start of data
   14285         if (iDataSourcePosParams.iMode == PVMF_SET_DATA_SOURCE_POSITION_MODE_NOW)
   14286         {
   14287             /* Reset */
   14288             iDataSourcePosParams.iActualMediaDataTS = 0;
   14289             iDataSourcePosParams.iActualNPT = 0;
   14290             iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_MODE_UNKNOWN;
   14291             iDataSourcePosParams.iPlayElementIndex = -1;
   14292             iDataSourcePosParams.iSeekToSyncPoint = true;
   14293             iDataSourcePosParams.iTargetNPT = 0;
   14294             SendInformationalEvent(PVMFInfoStartOfData);
   14295         }
   14296 
   14297         // send the actual playback position from where playback will resume after reposition.
   14298         PVPPlaybackPosition actualPlaybackPosition;
   14299         actualPlaybackPosition.iPosValue.millisec_value = iStartNPT;
   14300         actualPlaybackPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   14301 
   14302         PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14303         PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackFromBeginTime, puuid, NULL));
   14304         SendInformationalEvent(PVMFInfoActualPlaybackPosition, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&actualPlaybackPosition);
   14305         infomsg->removeRef();
   14306 
   14307         // Complete the SetPlaybackRange() or SetPlaybackRate()
   14308         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   14309     }
   14310 
   14311     if ((iNumPendingSkipCompleteEvent == 0) && (iNumPVMFInfoStartOfDataPending == 0))
   14312     {
   14313         if (iWatchDogTimer->IsBusy())
   14314         {
   14315             iWatchDogTimer->Cancel();
   14316         }
   14317         // we have received all the bos event for
   14318         // playback hasnt started yet
   14319 
   14320         StartPlaybackClock();
   14321         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback - PlayClock Started"));
   14322     }
   14323 
   14324     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Out"));
   14325 }
   14326 
   14327 
   14328 void PVPlayerEngine::HandleSourceNodePause(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14329 {
   14330     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePause() In"));
   14331 
   14332     switch (aNodeResp.GetCmdStatus())
   14333     {
   14334         case PVMFSuccess:
   14335         {
   14336             // Pause command is complete
   14337             SetEngineState(PVP_ENGINE_STATE_PAUSED);
   14338             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   14339         }
   14340         break;
   14341 
   14342         default:
   14343         {
   14344             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14345                             (0, "PVPlayerEngine::HandleSourceNodePause() failed, Add EH command"));
   14346             bool ehPending = CheckForPendingErrorHandlingCmd();
   14347             if (ehPending)
   14348             {
   14349                 // there should be no error handling queued.
   14350                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePause() Already EH pending, should never happen"));
   14351                 return;
   14352             }
   14353             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14354             if (aNodeResp.GetEventExtensionInterface())
   14355             {
   14356                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14357             }
   14358 
   14359             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14360             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   14361             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   14362 
   14363             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
   14364         }
   14365         break;
   14366     }
   14367 
   14368     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePause() Out"));
   14369 }
   14370 
   14371 
   14372 void PVPlayerEngine::HandleSourceNodeResume(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14373 {
   14374     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeResume() In"));
   14375 
   14376     PVMFStatus cmdstatus = PVMFErrNotSupported;
   14377 
   14378     switch (aNodeResp.GetCmdStatus())
   14379     {
   14380         case PVMFSuccess:
   14381         {
   14382             // Issue Skip on Sink Node and Start on datapaths back to back. This is done to make sure that
   14383             // sink node is started only after discarding the data from an earlier stream.
   14384             if (iChangePlaybackPositionWhenResuming || iChangePlaybackDirectionWhenResuming)
   14385             {
   14386                 PVMFStatus cmdstatus = DoSinkNodeSkipMediaData(aNodeContext.iCmdId, aNodeContext.iCmdContext);
   14387                 if (cmdstatus != PVMFSuccess)
   14388                 {
   14389                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Skip of sink node did a leave, asserting"));
   14390                     OSCL_ASSERT(false);
   14391                 }
   14392             }
   14393             // Issue start to all active datapaths
   14394             iNumPendingDatapathCmd = 0;
   14395             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   14396             {
   14397                 if (iDatapathList[i].iDatapath)
   14398                 {
   14399                     PVMFStatus retval = DoDatapathStart(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
   14400                     if (retval == PVMFSuccess)
   14401                     {
   14402                         ++iNumPendingDatapathCmd;
   14403                         cmdstatus = PVMFSuccess;
   14404                     }
   14405                     else
   14406                     {
   14407                         cmdstatus = retval;
   14408                         break;
   14409                     }
   14410                 }
   14411             }
   14412 
   14413             if (iNumPendingDatapathCmd == 0)
   14414             {
   14415                 bool ehPending = CheckForPendingErrorHandlingCmd();
   14416                 if (ehPending)
   14417                 {
   14418                     // there should be no error handling queued.
   14419                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Already EH pending, should never happen"));
   14420                     return;
   14421                 }
   14422                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Report command as failed, Add EH command"));
   14423                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   14424                 iCommandCompleteErrMsgInErrorHandling = NULL;
   14425                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   14426             }
   14427         }
   14428         break;
   14429 
   14430         default:
   14431         {
   14432             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() failed, Add EH command"));
   14433             bool ehPending = CheckForPendingErrorHandlingCmd();
   14434             if (ehPending)
   14435             {
   14436                 // there should be no error handling queued.
   14437                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Already EH pending, should never happen"));
   14438                 return;
   14439             }
   14440             cmdstatus = aNodeResp.GetCmdStatus();
   14441             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14442             if (aNodeResp.GetEventExtensionInterface())
   14443             {
   14444                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14445             }
   14446 
   14447             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14448             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   14449             iCommandCompleteStatusInErrorHandling = cmdstatus;
   14450 
   14451             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   14452         }
   14453         break;
   14454     }
   14455 
   14456     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeResume() Out"));
   14457 }
   14458 
   14459 
   14460 void PVPlayerEngine::HandleSourceNodeStop(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14461 {
   14462     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStop() In"));
   14463 
   14464     PVMFStatus cmdstatus = PVMFFailure;
   14465 
   14466     switch (aNodeResp.GetCmdStatus())
   14467     {
   14468         case PVMFSuccess:
   14469         {
   14470             // Issue teardown sequence to all active datapaths
   14471             iNumPendingDatapathCmd = 0;
   14472             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   14473             {
   14474                 if (iDatapathList[i].iDatapath)
   14475                 {
   14476                     PVMFStatus retval = DoDatapathTeardown(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
   14477                     if (retval == PVMFSuccess)
   14478                     {
   14479                         ++iNumPendingDatapathCmd;
   14480                         cmdstatus = PVMFSuccess;
   14481                     }
   14482                     else
   14483                     {
   14484                         cmdstatus = retval;
   14485                         break;
   14486                     }
   14487                 }
   14488             }
   14489         }
   14490 
   14491         if (iNumPendingDatapathCmd == 0)
   14492         {
   14493             bool ehPending = CheckForPendingErrorHandlingCmd();
   14494             if (ehPending)
   14495             {
   14496                 // there should be no error handling queued.
   14497                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStop() Already EH pending, should never happen"));
   14498                 return;
   14499             }
   14500             // No active datapath to shutdown - not possible in stop
   14501             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStop() Datapath Teardown failed, Add EH command"));
   14502             iCommandCompleteErrMsgInErrorHandling = NULL;
   14503             iCommandCompleteStatusInErrorHandling = cmdstatus;
   14504             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   14505         }
   14506         break;
   14507 
   14508         default:
   14509         {
   14510             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14511                             (0, "PVPlayerEngine::HandleSourceNodeStop() Source node stop failed, go in error handling, Add EH command"));
   14512             bool ehPending = CheckForPendingErrorHandlingCmd();
   14513             if (ehPending)
   14514             {
   14515                 // there should be no error handling queued.
   14516                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStop() Already EH pending, should never happen"));
   14517                 return;
   14518             }
   14519             cmdstatus = aNodeResp.GetCmdStatus();
   14520             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14521             if (aNodeResp.GetEventExtensionInterface())
   14522             {
   14523                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14524             }
   14525 
   14526             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14527             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   14528             iCommandCompleteStatusInErrorHandling = cmdstatus;
   14529 
   14530             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   14531         }
   14532         break;
   14533     }
   14534 
   14535     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStop() Out"));
   14536 }
   14537 
   14538 
   14539 void PVPlayerEngine::HandleSourceNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14540 {
   14541     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeReset() In"));
   14542 
   14543     PVMFStatus cmdstatus = PVMFErrNotSupported;
   14544 
   14545     if (aNodeResp.GetCmdStatus() == PVMFSuccess)
   14546     {
   14547         if (iSourceNode->GetState() != EPVMFNodeIdle)
   14548         {
   14549             // when reset completes on Source node, source node should be in Idle State,
   14550             // If not then just assert.
   14551             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14552                             (0, "PVPlayerEngine::HandleSourceNodeReset() Source Node not in a idle state after reset, Asserting"));
   14553             OSCL_ASSERT(false);
   14554         }
   14555 
   14556         PVMFStatus status = PVMFFailure;
   14557         status = iSourceNode->ThreadLogoff();
   14558         if (status != PVMFSuccess)
   14559         {
   14560             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Threadlogoff on SourceNode Failed"));
   14561             OSCL_ASSERT(false);
   14562         }
   14563 
   14564         if (iSourceNode->GetState() != EPVMFNodeCreated)
   14565         {
   14566             // when reset completes on Source node, source node should be in Idle State,
   14567             // If not then just assert.
   14568             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14569                             (0, "PVPlayerEngine::HandleSourceNodeReset() Source Node not in a created state after threadlogoff, Asserting"));
   14570             OSCL_ASSERT(false);
   14571         }
   14572 
   14573         // Reset active datapaths
   14574         if (!iDatapathList.empty())
   14575         {
   14576             iNumPendingDatapathCmd = 0;
   14577             PVMFCommandId cmdid = -1;
   14578             int32 leavecode = 0;
   14579             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   14580             {
   14581                 if ((iDatapathList[i].iDatapath != NULL) &&
   14582                         (iDatapathList[i].iTrackInfo != NULL) &&
   14583                         (iDatapathList[i].iDatapath->iState != PVPDP_IDLE))
   14584                 {
   14585                     PVMFStatus retval = DoDatapathReset(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
   14586                     if (retval == PVMFSuccess)
   14587                     {
   14588                         ++iNumPendingDatapathCmd;
   14589                         cmdstatus = PVMFSuccess;
   14590                     }
   14591                     else
   14592                     {
   14593                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14594                                         (0, "PVPlayerEngine::HandleSourceNodeReset() Reset failed, Asserting"));
   14595                         OSCL_ASSERT(false);
   14596                         break;
   14597                     }
   14598                 }
   14599                 else if (iDatapathList[i].iDecNode != NULL)
   14600                 {
   14601                     // This happens in case of error during prepare, when datapaths have not yet
   14602                     // been fully constructed.
   14603                     // reset the decoder node during inteligent track selection
   14604                     // Call Reset() on the decoder node
   14605                     PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iDecNode, NULL, aNodeContext.iCmdId, aNodeContext.iCmdContext, PVP_CMD_DecNodeReset);
   14606 
   14607                     leavecode = IssueDecNodeReset(iDatapathList[i].iDecNode, iDatapathList[i].iDecNodeSessionId, (OsclAny*) context, cmdid);
   14608 
   14609                     if (cmdid != -1 && leavecode == 0)
   14610                     {
   14611                         ++iNumPendingDatapathCmd;
   14612                     }
   14613                     else
   14614                     {
   14615                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeReset() Reset on dec node leaved, asserting"));
   14616                         FreeEngineContext(context);
   14617                         OSCL_ASSERT(false);
   14618                     }
   14619                 }
   14620                 else if (iDatapathList[i].iSinkNode != NULL)
   14621                 {
   14622                     // This happens in case of error during prepare, when datapaths have not yet
   14623                     // been fully constructed.
   14624                     // reset the sink node during inteligent track selection
   14625                     // Call Reset() on the sink node
   14626                     PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aNodeContext.iCmdId, aNodeContext.iCmdContext, PVP_CMD_SinkNodeReset);
   14627 
   14628                     leavecode = IssueSinkNodeReset(&(iDatapathList[i]), (OsclAny*) context, cmdid);
   14629 
   14630                     if (cmdid != -1 && leavecode == 0)
   14631                     {
   14632                         ++iNumPendingDatapathCmd;
   14633                     }
   14634                     else
   14635                     {
   14636                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeReset() Reset on sink node leaved, asserting"));
   14637                         FreeEngineContext(context);
   14638                         OSCL_ASSERT(false);
   14639                     }
   14640                 }
   14641                 else
   14642                 {
   14643                     // No Sink nodes and no datapaths created yet so just do Enginedatapath Teardown.
   14644                     DoEngineDatapathTeardown(iDatapathList[i]);
   14645                 }
   14646             }
   14647 
   14648             if (iNumPendingDatapathCmd == 0)
   14649             {
   14650                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14651                                 (0, "PVPlayerEngine::HandleSourceNodeReset() Reset on SourceNode completed and no datapath or sink node to reset."));
   14652                 // Reset on source node is complete and there are no datapaths or sink nodes to reset,
   14653                 // now need to remove the data sinks and sources
   14654                 // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
   14655                 SetEngineState(PVP_ENGINE_STATE_IDLE);
   14656                 RunIfNotReady();
   14657             }
   14658         }
   14659         else
   14660         {
   14661             // Reset on source node is complete and there are no datapaths or sink nodes to reset,
   14662             // now need to remove the data sinks and sources
   14663             // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
   14664             SetEngineState(PVP_ENGINE_STATE_IDLE);
   14665             RunIfNotReady();
   14666         }
   14667     }
   14668     else
   14669     {
   14670         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14671                         (0, "PVPlayerEngine::HandleSourceNodeReset() Reset failed on Source Node, Asserting"));
   14672         OSCL_ASSERT(false);
   14673     }
   14674 
   14675     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeReset() Out"));
   14676 }
   14677 
   14678 
   14679 void PVPlayerEngine::HandleSinkNodePause(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14680 {
   14681     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodePause() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   14682 
   14683     // Decrement the counter for pending cmds
   14684     --iNumPendingDatapathCmd;
   14685 
   14686     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   14687     {
   14688         bool ehPending = CheckForPendingErrorHandlingCmd();
   14689         if (ehPending)
   14690         {
   14691             // there should be no error handling queued.
   14692             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodePause() Already EH pending, should never happen"));
   14693             return;
   14694         }
   14695         else
   14696         {
   14697             // Cancel any pending node/datapath commands
   14698             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodePause() Failed, Add EH command"));
   14699             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14700             if (aNodeResp.GetEventExtensionInterface())
   14701             {
   14702                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14703             }
   14704 
   14705             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14706             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkFatal, puuid, nextmsg));
   14707             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   14708             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
   14709         }
   14710 
   14711         return;
   14712     }
   14713 
   14714     if (iNumPendingDatapathCmd == 0)
   14715     {
   14716         // Auto-pause is complete
   14717         SetEngineState(PVP_ENGINE_STATE_AUTO_PAUSED);
   14718         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodePause() Report command as success"));
   14719         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   14720     }
   14721 
   14722     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodePause() Out"));
   14723 }
   14724 
   14725 
   14726 void PVPlayerEngine::HandleSinkNodeResume(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14727 {
   14728     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeResume() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   14729 
   14730     // Decrement the counter for pending cmds
   14731     --iNumPendingDatapathCmd;
   14732 
   14733     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   14734     {
   14735         bool ehPending = CheckForPendingErrorHandlingCmd();
   14736         if (ehPending)
   14737         {
   14738             // there should be no error handling queued.
   14739             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeResume() Already EH pending, should never happen"));
   14740             return;
   14741         }
   14742         else
   14743         {
   14744             // Cancel any pending node/datapath commands
   14745             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeResume() Failed, Add EH command"));
   14746             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14747             if (aNodeResp.GetEventExtensionInterface())
   14748             {
   14749                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   14750             }
   14751 
   14752             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14753             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkFatal, puuid, nextmsg));
   14754             iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
   14755             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
   14756         }
   14757         return;
   14758     }
   14759 
   14760     if (iNumPendingDatapathCmd == 0)
   14761     {
   14762         // Auto-resume is complete
   14763         // Resume the playback clock only if InfoStartofData has been received for all tracks.
   14764         // If SetPlaybackRange is called in Auto-Pause state, its possible that engine is waiting for InfoStartofData.
   14765         // If waiting, restart the watchdog timer which was cancelled in Auto-Pause command.
   14766         // this should only be done when engine is waiting for StartofData info event
   14767         // after reposition. If already busy after SetPlaybackRange command complete,
   14768         // then cancel it and start again. Playback clock will be started in either HandleSinkNodeInfoEvent or
   14769         // PVPlayerWatchdogTimerEvent
   14770         if (iNumPVMFInfoStartOfDataPending > 0)
   14771         {
   14772             if (iWatchDogTimerInterval > 0)
   14773             {
   14774                 if (iWatchDogTimer->IsBusy())
   14775                 {
   14776                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   14777                                     (0, "PVPlayerEngine::HandleSinkNodeResume - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
   14778                     iWatchDogTimer->Cancel();
   14779                 }
   14780 
   14781                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   14782                                 (0, "PVPlayerEngine::HandleSinkNodeResume Setting WatchDogTimer for %d ms, iNumPVMFInfoStartOfDataPending=%d",
   14783                                  iWatchDogTimerInterval, iNumPVMFInfoStartOfDataPending));
   14784                 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
   14785                 iWatchDogTimer->Start();
   14786             }
   14787         }
   14788         // Auto-resume is complete & not waiting on PVMFInfoStartOfData, so go ahead and
   14789         // start the clock
   14790         if (iNumPVMFInfoStartOfDataPending == 0)
   14791         {
   14792             StartPlaybackClock();
   14793 
   14794             // Notify data sinks that clock has started
   14795             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   14796             {
   14797                 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   14798                 {
   14799                     iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
   14800                 }
   14801             }
   14802         }
   14803 
   14804         SetEngineState(PVP_ENGINE_STATE_STARTED);
   14805         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeResume() Report command as success"));
   14806         EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   14807     }
   14808 
   14809     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeResume() Out"));
   14810 }
   14811 
   14812 void PVPlayerEngine::HandleSinkNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14813 {
   14814     OSCL_ASSERT(aNodeContext.iEngineDatapath != NULL);
   14815     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeReset() In"));
   14816 
   14817     // Decrement the counter for pending cmds
   14818     --iNumPendingDatapathCmd;
   14819 
   14820     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   14821     {
   14822         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14823                         (0, "PVPlayerEngine::HandleSinkNodeReset() Reset failed, assert"));
   14824         OSCL_ASSERT(false);
   14825         return;
   14826     }
   14827     else
   14828     {
   14829         // Reset for this sink node is complete
   14830         //a sync call in engine - no async cmds issued here
   14831         DoEngineDatapathTeardown(*(aNodeContext.iEngineDatapath));
   14832     }
   14833 
   14834     if (iNumPendingDatapathCmd == 0)
   14835     {
   14836         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14837                         (0, "PVPlayerEngine::HandleSinkNodeReset() Reset on SourceNode and Sink nodes completed"));
   14838         // Reset on source node and sink node is complete, now need to remove the data sinks and sources
   14839         // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
   14840         SetEngineState(PVP_ENGINE_STATE_IDLE);
   14841         RunIfNotReady();
   14842     }
   14843 
   14844     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeReset() Out"));
   14845 }
   14846 
   14847 void PVPlayerEngine::HandleDecNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   14848 {
   14849     OSCL_ASSERT(aNodeContext.iEngineDatapath != NULL);
   14850     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeReset() In"));
   14851 
   14852     // Decrement the counter for pending cmds
   14853     --iNumPendingDatapathCmd;
   14854 
   14855     if (aNodeResp.GetCmdStatus() != PVMFSuccess)
   14856     {
   14857         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14858                         (0, "PVPlayerEngine::HandleDecNodeReset() Reset failed, assert"));
   14859         OSCL_ASSERT(false);
   14860         return;
   14861     }
   14862 
   14863     if (iNumPendingDatapathCmd == 0)
   14864     {
   14865         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14866                         (0, "PVPlayerEngine::HandleDecNodeReset() Reset on SourceNode and dec nodes completed, now reset Sink nodes"));
   14867         // Reset on source node and dec node is complete, now need to reset the sink nodes
   14868         if (!iDatapathList.empty())
   14869         {
   14870             iNumPendingDatapathCmd = 0;
   14871             PVMFCommandId cmdid = -1;
   14872             int32 leavecode = 0;
   14873             for (uint32 i = 0; i < iDatapathList.size(); ++i)
   14874             {
   14875                 if (iDatapathList[i].iSinkNode != NULL)
   14876                 {
   14877                     // This happens in case of error during prepare, when datapaths have not yet
   14878                     // been fully constructed.
   14879                     // reset the sink node during inteligent track selection
   14880                     // Call Reset() on the sink node
   14881                     PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aNodeContext.iCmdId, aNodeContext.iCmdContext, PVP_CMD_SinkNodeReset);
   14882 
   14883                     leavecode = IssueSinkNodeReset(&(iDatapathList[i]), (OsclAny*) context, cmdid);
   14884 
   14885                     if (cmdid != -1 && leavecode == 0)
   14886                     {
   14887                         ++iNumPendingDatapathCmd;
   14888                     }
   14889                     else
   14890                     {
   14891                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeReset() Reset on sink node leaved, asserting"));
   14892                         FreeEngineContext(context);
   14893                         OSCL_ASSERT(false);
   14894                     }
   14895                 }
   14896             }
   14897         }
   14898     }
   14899 
   14900     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeReset() Out"));
   14901 }
   14902 
   14903 void PVPlayerEngine::HandleDatapathPrepare(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   14904 {
   14905     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   14906                     (0, "PVPlayerEngine::HandleDatapathPrepare() for %s Tick=%d",
   14907                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   14908 
   14909     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPrepare() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   14910 
   14911     // Decrement the counter for pending datapath cmds
   14912     --iNumPendingDatapathCmd;
   14913 
   14914     if (aDatapathStatus != PVMFSuccess)
   14915     {
   14916         bool ehPending = CheckForPendingErrorHandlingCmd();
   14917         if (ehPending)
   14918         {
   14919             // there should be no error handling queued.
   14920             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPrepare() Already EH pending, should never happen"));
   14921             return;
   14922         }
   14923         else
   14924         {
   14925             // Cancel any pending node/datapath commands
   14926             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   14927                             (0, "PVPlayerEngine::HandleDatapathPrepare() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   14928             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   14929             if (aCmdResp)
   14930             {
   14931                 if (aCmdResp->GetEventExtensionInterface())
   14932                 {
   14933                     nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
   14934                 }
   14935             }
   14936 
   14937             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   14938             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   14939             iCommandCompleteStatusInErrorHandling = aDatapathStatus;
   14940             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   14941         }
   14942         return;
   14943     }
   14944 
   14945     if (iNumPendingDatapathCmd == 0)
   14946     {
   14947         // Reposition and/or start the source node
   14948         PVMFStatus cmdstatus = DoSourceNodeQueryDataSourcePosition(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
   14949         if (cmdstatus != PVMFSuccess)
   14950         {
   14951             // Setting position not supported so start the source node
   14952             cmdstatus = DoSourceNodeStart(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
   14953         }
   14954 
   14955         if (cmdstatus != PVMFSuccess)
   14956         {
   14957             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPrepare() Report command as failed, Add EH command"));
   14958             bool ehPending = CheckForPendingErrorHandlingCmd();
   14959             if (ehPending)
   14960             {
   14961                 // there should be no error handling queued.
   14962                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPrepare() Already EH pending, should never happen"));
   14963                 return;
   14964             }
   14965             else
   14966             {
   14967                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   14968                 iCommandCompleteErrMsgInErrorHandling = NULL;
   14969                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   14970             }
   14971         }
   14972     }
   14973 
   14974     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPrepare() Out"));
   14975 }
   14976 
   14977 
   14978 void PVPlayerEngine::HandleDatapathStart(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   14979 {
   14980     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   14981                     (0, "PVPlayerEngine::HandleDatapathStart() for %s Tick=%d",
   14982                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   14983 
   14984     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStart() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   14985 
   14986     // Decrement the counter for pending datapath cmds
   14987     --iNumPendingDatapathCmd;
   14988 
   14989     if (aDatapathStatus != PVMFSuccess)
   14990     {
   14991         bool ehPending = CheckForPendingErrorHandlingCmd();
   14992         if (ehPending)
   14993         {
   14994             // there should be no error handling queued.
   14995             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStart() Already EH pending, should never happen"));
   14996             return;
   14997         }
   14998         else
   14999         {
   15000             // Cancel any pending node/datapath commands
   15001             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15002                             (0, "PVPlayerEngine::HandleDatapathStart() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15003             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15004             if (aCmdResp)
   15005             {
   15006                 if (aCmdResp->GetEventExtensionInterface())
   15007                 {
   15008                     nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
   15009                 }
   15010             }
   15011 
   15012             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15013             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   15014             iCommandCompleteStatusInErrorHandling = aDatapathStatus;
   15015             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
   15016         }
   15017         return;
   15018     }
   15019 
   15020     if (iNumPendingDatapathCmd == 0)
   15021     {
   15022         // This should never be happen if Skip on sink node has not completed (i.e. iNumPendingSkipCompleteEvent
   15023         // is greater than zero). If this happens with iNumPendingSkipCompleteEvent > 0 then just assert.
   15024         // Set the clock to the specified begin time just before Start of playback Clock
   15025         iPlaybackClock.Stop();
   15026         bool overflow = 0;
   15027         iPlaybackClock.SetStartTime32(iSkipMediaDataTS, PVMF_MEDIA_CLOCK_MSEC, overflow);
   15028 
   15029         if (!(iWatchDogTimer->IsBusy()))
   15030         {
   15031             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   15032                             (0, "PVPlayerEngine::HandleDatapathStart() Setting WatchDogTimer for %d ms, TargetNPT=%d  ActualNPT=%d, if interval zero set to default 1 second",
   15033                              iWatchDogTimerInterval, iTargetNPT, iActualNPT));
   15034             iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
   15035             iWatchDogTimer->Start();
   15036         }
   15037         // Set the actual playback position to the requested time since actual media data TS was adjusted
   15038         // This is important since the difference between the two is used to calculate the NPT to media data offset
   15039         // This is not required here as the ActualPlaybackPosition is already adjusted before calling Skip on Sink Node.
   15040         // iActualNPT=iCurrentBeginPosition.iPosValue.millisec_value;
   15041 
   15042         // Save the start NPT and TS
   15043         iStartNPT = iActualNPT;
   15044         iStartMediaDataTS = iSkipMediaDataTS;
   15045         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO,
   15046                         (0, "PVPlayerEngine::HandleDatapathStart() TargetNPT %d, StartNPT %d StartTS %d",
   15047                          iTargetNPT, iStartNPT, iStartMediaDataTS));
   15048         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   15049                         (0, "PVPlayerEngine::HandleDatapathStart() TargetNPT %d, StartNPT %d StartTS %d",
   15050                          iTargetNPT, iStartNPT, iStartMediaDataTS));
   15051 
   15052         SetEngineState(PVP_ENGINE_STATE_PREPARED);
   15053 
   15054         // send the actual playback position from where playback will resume after reposition.
   15055         PVPPlaybackPosition actualPlaybackPosition;
   15056         actualPlaybackPosition.iPosValue.millisec_value = iStartNPT;
   15057         actualPlaybackPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   15058 
   15059         PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15060         PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackFromBeginTime, puuid, NULL));
   15061         SendInformationalEvent(PVMFInfoActualPlaybackPosition, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&actualPlaybackPosition);
   15062         infomsg->removeRef();
   15063 
   15064         EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, PVMFSuccess);
   15065     }
   15066 
   15067     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStart() Out"));
   15068 }
   15069 
   15070 
   15071 void PVPlayerEngine::HandleDatapathPause(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   15072 {
   15073     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   15074                     (0, "PVPlayerEngine::HandleDatapathPause() for %s Tick=%d",
   15075                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   15076 
   15077     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPause() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15078 
   15079     // Decrement the counter for pending datapath cmds
   15080     --iNumPendingDatapathCmd;
   15081 
   15082     if (aDatapathStatus != PVMFSuccess)
   15083     {
   15084         bool ehPending = CheckForPendingErrorHandlingCmd();
   15085         if (ehPending)
   15086         {
   15087             // there should be no error handling queued.
   15088             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPause() Already EH pending, should never happen"));
   15089             return;
   15090         }
   15091         else
   15092         {
   15093             // Cancel any pending node/datapath commands
   15094             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15095                             (0, "PVPlayerEngine::HandleDatapathPause() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15096             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15097             if (aCmdResp)
   15098             {
   15099                 if (aCmdResp->GetEventExtensionInterface())
   15100                 {
   15101                     nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
   15102                 }
   15103             }
   15104 
   15105             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15106             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   15107             iCommandCompleteStatusInErrorHandling = aDatapathStatus;
   15108             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
   15109         }
   15110         return;
   15111     }
   15112 
   15113     if (iNumPendingDatapathCmd == 0)
   15114     {
   15115         // Continue on by pauseing the source node
   15116         PVMFStatus cmdstatus = DoSourceNodePause(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
   15117 
   15118         if (cmdstatus != PVMFSuccess)
   15119         {
   15120             bool ehPending = CheckForPendingErrorHandlingCmd();
   15121             if (ehPending)
   15122             {
   15123                 // there should be no error handling queued.
   15124                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPause() Already EH pending, should never happen"));
   15125                 return;
   15126             }
   15127             else
   15128             {
   15129                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPause() Report command as failed, Add EH command"));
   15130                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   15131                 iCommandCompleteErrMsgInErrorHandling = NULL;
   15132                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
   15133             }
   15134         }
   15135     }
   15136 
   15137     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPause() Out"));
   15138 }
   15139 
   15140 
   15141 void PVPlayerEngine::HandleDatapathResume(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   15142 {
   15143     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   15144                     (0, "PVPlayerEngine::HandleDatapathResume() for %s Tick=%d",
   15145                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   15146 
   15147     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathResume() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15148 
   15149     // Decrement the counter for pending datapath cmds
   15150     --iNumPendingDatapathCmd;
   15151 
   15152     if (aDatapathStatus != PVMFSuccess)
   15153     {
   15154         bool ehPending = CheckForPendingErrorHandlingCmd();
   15155         if (ehPending)
   15156         {
   15157             // there should be no error handling queued.
   15158             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathResume() Already EH pending, should never happen"));
   15159             return;
   15160         }
   15161         else
   15162         {
   15163             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15164                             (0, "PVPlayerEngine::HandleDatapathResume() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15165             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15166             if (aCmdResp)
   15167             {
   15168                 if (aCmdResp->GetEventExtensionInterface())
   15169                 {
   15170                     nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
   15171                 }
   15172             }
   15173 
   15174             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15175             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   15176             iCommandCompleteStatusInErrorHandling = aDatapathStatus;
   15177             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   15178         }
   15179         return;
   15180     }
   15181 
   15182     if (iNumPendingDatapathCmd == 0)
   15183     {
   15184         if (iChangePlaybackPositionWhenResuming || iChangePlaybackDirectionWhenResuming)
   15185         {
   15186             // This should never be happen if Skip on sink node has not completed (i.e. iNumPendingSkipCompleteEvent
   15187             // is greater than zero). If this happens with iNumPendingSkipCompleteEvent > 0 then just assert.
   15188             // Set the clock to the specified begin time just before Start of playback Clock
   15189             iPlaybackClock.Stop();
   15190             bool overflow = 0;
   15191             iPlaybackClock.SetStartTime32(iSkipMediaDataTS, PVMF_MEDIA_CLOCK_MSEC, overflow);
   15192 
   15193             if (iNumPVMFInfoStartOfDataPending == 0)
   15194             {
   15195                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   15196                                 (0, "PVPlayerEngine::HandleDatapathResume() Skipping WatchDogTimer - Starting PlayBackClock"));
   15197                 StartPlaybackClock();
   15198             }
   15199             else
   15200             {
   15201                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   15202                                 (0, "PVPlayerEngine::HandleDatapathResume() Setting WatchDogTimer for %d ms, TargetNPT=%d  ActualNPT=%d",
   15203                                  iWatchDogTimerInterval, iTargetNPT, iActualNPT));
   15204 
   15205                 // There can be a case in which WatchDogTimerInterval is zero and iNumPVMFInfoStartOfDataPending is greater than zero.
   15206                 // In this case it is possible InfoStartofData is not sent by Sink Nodes for some time and player hangs. To avoid the player hang
   15207                 // set the watchdog timer Interval to the default value of 1 second.
   15208                 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
   15209                 iWatchDogTimer->Start();
   15210             }
   15211 
   15212             // Set the actual playback position to the requested time since actual media data TS was adjusted
   15213             // This is important since the difference between the two is used to calculate the NPT to media data offset
   15214             // This is not required here as the ActualPlaybackPosition is already adjusted before calling Skip on Sink Node.
   15215             // iActualNPT=iCurrentBeginPosition.iPosValue.millisec_value;
   15216 
   15217             //clear the pending direction change NPT.
   15218             iChangeDirectionNPT.iIndeterminate = true;
   15219             // Save the start NPT and TS
   15220             iStartNPT = iActualNPT;
   15221             iStartMediaDataTS = iSkipMediaDataTS;
   15222             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO,
   15223                             (0, "PVPlayerEngine::HandleDatapathResume() TargetNPT %d, ActualNPT %d StartTS %d",
   15224                              iTargetNPT, iStartNPT, iStartMediaDataTS));
   15225             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   15226                             (0, "PVPlayerEngine::HandleDatapathResume() TargetNPT %d, ActualNPT %d StartTS %d",
   15227                              iTargetNPT, iStartNPT, iStartMediaDataTS));
   15228 
   15229             // send the actual playback position from where playback will resume after reposition.
   15230             PVPPlaybackPosition actualPlaybackPosition;
   15231             actualPlaybackPosition.iPosValue.millisec_value = iStartNPT;
   15232             actualPlaybackPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   15233 
   15234             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15235             PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackFromBeginTime, puuid, NULL));
   15236             SendInformationalEvent(PVMFInfoActualPlaybackPosition, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&actualPlaybackPosition);
   15237             infomsg->removeRef();
   15238         }
   15239         else
   15240         {
   15241             // Resume the playback clock - only if we have come out of any previous auto pause, if any
   15242             if (iPlaybackClock.GetState() == PVMFMediaClock::PAUSED)
   15243             {
   15244                 StartPlaybackClock();
   15245 
   15246                 // Notify all sink nodes that have sync control IF that clock has started
   15247                 for (uint32 i = 0; i < iDatapathList.size(); ++i)
   15248                 {
   15249                     if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   15250                     {
   15251                         iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
   15252                     }
   15253                 }
   15254             }
   15255 
   15256             // Restart the watchdog timer which was cancelled in Pause command.
   15257             // this should only be done when engine is waiting for StartofData info event
   15258             // after reposition.
   15259             if (iNumPVMFInfoStartOfDataPending > 0)
   15260             {
   15261                 if (iWatchDogTimerInterval > 0)
   15262                 {
   15263                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
   15264                                     (0, "PVPlayerEngine::HandleDatapathResume Setting WatchDogTimer for %d ms, iNumPVMFInfoStartOfDataPending=%d",
   15265                                      iWatchDogTimerInterval, iNumPVMFInfoStartOfDataPending));
   15266                     iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
   15267                     iWatchDogTimer->Start();
   15268                 }
   15269             }
   15270 
   15271             // Restart the end time check if enabled
   15272             if (iEndTimeCheckEnabled)
   15273             {
   15274                 // Determine the check cycle based on interval setting in milliseconds
   15275                 // and timer frequency of 100 millisec
   15276                 int32 checkcycle = iEndTimeCheckInterval / 100;
   15277                 if (checkcycle == 0)
   15278                 {
   15279                     ++checkcycle;
   15280                 }
   15281                 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   15282                 iPollingCheckTimer->Request(PVPLAYERENGINE_TIMERID_ENDTIMECHECK, 0, checkcycle, this, true);
   15283             }
   15284         }
   15285 
   15286         SetEngineState(PVP_ENGINE_STATE_STARTED);
   15287 
   15288         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathResume() Report command as completed"));
   15289         EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, PVMFSuccess);
   15290     }
   15291 
   15292     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathResume() Out"));
   15293 }
   15294 
   15295 
   15296 void PVPlayerEngine::HandleDatapathStop(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   15297 {
   15298     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   15299                     (0, "PVPlayerEngine::HandleDatapathStop() for %s Tick=%d",
   15300                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   15301 
   15302     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStop() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15303 
   15304     // Decrement the counter for pending datapath cmds
   15305     --iNumPendingDatapathCmd;
   15306 
   15307     if (aDatapathStatus != PVMFSuccess)
   15308     {
   15309         bool ehPending = CheckForPendingErrorHandlingCmd();
   15310         if (ehPending)
   15311         {
   15312             // there should be no error handling queued.
   15313             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStop() Already EH pending, should never happen"));
   15314             return;
   15315         }
   15316         else
   15317         {
   15318             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15319                             (0, "PVPlayerEngine::HandleDatapathStop() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15320             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15321             if (aCmdResp)
   15322             {
   15323                 if (aCmdResp->GetEventExtensionInterface())
   15324                 {
   15325                     nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
   15326                 }
   15327             }
   15328 
   15329             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15330             iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   15331             iCommandCompleteStatusInErrorHandling = aDatapathStatus;
   15332             AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   15333         }
   15334         return;
   15335     }
   15336 
   15337     if (iNumPendingDatapathCmd == 0)
   15338     {
   15339         // Continue on by stopping the source node
   15340         PVMFStatus cmdstatus = DoSourceNodeStop(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
   15341 
   15342         if (cmdstatus != PVMFSuccess)
   15343         {
   15344             bool ehPending = CheckForPendingErrorHandlingCmd();
   15345             if (ehPending)
   15346             {
   15347                 // there should be no error handling queued.
   15348                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStop() Already EH pending, should never happen"));
   15349                 return;
   15350             }
   15351             else
   15352             {
   15353                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStop() Report command as failed, Add EH command"));
   15354                 iCommandCompleteErrMsgInErrorHandling = NULL;
   15355                 iCommandCompleteStatusInErrorHandling = cmdstatus;
   15356                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   15357             }
   15358         }
   15359     }
   15360 
   15361     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStop() Out"));
   15362 }
   15363 
   15364 
   15365 void PVPlayerEngine::HandleDatapathTeardown(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   15366 {
   15367     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   15368                     (0, "PVPlayerEngine::HandleDatapathTeardown() for %s Tick=%d",
   15369                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   15370 
   15371     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathTeardown() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15372 
   15373     PVMFStatus cmdstatus;
   15374 
   15375     switch (aDatapathStatus)
   15376     {
   15377         case PVMFSuccess:
   15378             // Reset this datapath next
   15379             cmdstatus = DoDatapathReset(*(aDatapathContext.iEngineDatapath), aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
   15380             break;
   15381 
   15382         default:
   15383         {
   15384             bool ehPending = CheckForPendingErrorHandlingCmd();
   15385             if (ehPending)
   15386             {
   15387                 // there should be no error handling queued.
   15388                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathTeardown() Already EH pending, should never happen"));
   15389                 return;
   15390             }
   15391             else
   15392             {
   15393                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15394                                 (0, "PVPlayerEngine::HandleDatapathTeardown() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15395                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15396                 if (aCmdResp)
   15397                 {
   15398                     if (aCmdResp->GetEventExtensionInterface())
   15399                     {
   15400                         nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
   15401                     }
   15402                 }
   15403 
   15404                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15405                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   15406                 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
   15407                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
   15408             }
   15409             return;
   15410         }
   15411     }
   15412 
   15413     if (cmdstatus != PVMFSuccess)
   15414     {
   15415         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathTeardown() Reset failed, asserting"));
   15416         OSCL_ASSERT(false);
   15417         EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, cmdstatus);
   15418     }
   15419 
   15420     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleVideoDatapathTeardown() Out"));
   15421 }
   15422 
   15423 
   15424 void PVPlayerEngine::HandleDatapathReset(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
   15425 {
   15426     OSCL_UNUSED_ARG(aCmdResp);
   15427 
   15428     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
   15429                     (0, "PVPlayerEngine::HandleDatapathReset() for %s Tick=%d",
   15430                      aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
   15431 
   15432     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathReset() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15433 
   15434     // Decrement the counter for pending datapath cmds
   15435     --iNumPendingDatapathCmd;
   15436 
   15437     if (aDatapathStatus != PVMFSuccess)
   15438     {
   15439         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15440                         (0, "PVPlayerEngine::HandleDatapathReset() In %s Reset failed, assert", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
   15441         OSCL_ASSERT(false);
   15442         return;
   15443     }
   15444     else
   15445     {
   15446         // Reset for this datapath is complete
   15447         //a sync call in engine - no async cmds issued here
   15448         DoEngineDatapathTeardown(*(aDatapathContext.iEngineDatapath));
   15449     }
   15450 
   15451     //this means datapath reset and teardown is complete for all datapaths
   15452     if (iNumPendingDatapathCmd == 0)
   15453     {
   15454         if (iState == PVP_ENGINE_STATE_RESETTING)
   15455         {
   15456             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15457                             (0, "PVPlayerEngine::HandleDatapathReset() Reset on SourceNode and Datapath completed"));
   15458             // Reset on source node and datapath is complete, now need to remove the data sinks and sources
   15459             // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
   15460             SetEngineState(PVP_ENGINE_STATE_IDLE);
   15461             RunIfNotReady();
   15462         }
   15463         else if (iState == PVP_ENGINE_STATE_STOPPING)
   15464         {
   15465             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathReset() Stop Completed"));
   15466             // stop has completed
   15467             SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
   15468             EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, PVMFSuccess);
   15469         }
   15470         else
   15471         {
   15472             //engine cannot be in any other state
   15473             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15474                             (0, "PVPlayerEngine::HandleDatapathReset() Wrong Engine state for Reset to complete, asserting"));
   15475             OSCL_ASSERT(false);
   15476         }
   15477     }
   15478 
   15479     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathReset() Out"));
   15480 }
   15481 
   15482 void PVPlayerEngine::HandleSourceNodeGetLicense(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   15483 {
   15484     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeGetLicense() In"));
   15485 
   15486     switch (aNodeResp.GetCmdStatus())
   15487     {
   15488         case PVMFSuccess:
   15489             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   15490             break;
   15491 
   15492         case PVMFErrCancelled:
   15493         default:
   15494         {
   15495             // report command complete
   15496             PVMFStatus cmdstatus = aNodeResp.GetCmdStatus();
   15497 
   15498             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15499             if (aNodeResp.GetEventExtensionInterface())
   15500             {
   15501                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   15502             }
   15503 
   15504             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15505             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
   15506             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg));
   15507             errmsg->removeRef();
   15508 
   15509         }
   15510         break;
   15511     }
   15512     /* Set CancelAcquireLicense cmd in current cmd */
   15513     if (!iCmdToDlaCancel.empty())
   15514     {
   15515         iCurrentCmd.push_front(iCmdToDlaCancel[0]);
   15516         iCmdToDlaCancel.clear();
   15517     }
   15518 }
   15519 
   15520 void PVPlayerEngine::HandleSourceNodeCancelGetLicense(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
   15521 {
   15522     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeCancelGetLicense() In"));
   15523 
   15524     switch (aNodeResp.GetCmdStatus())
   15525     {
   15526         case PVMFSuccess:
   15527             EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
   15528             break;
   15529 
   15530         default:
   15531         {
   15532             /* report command complete */
   15533             PVMFStatus cmdstatus = aNodeResp.GetCmdStatus();
   15534 
   15535             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15536             if (aNodeResp.GetEventExtensionInterface())
   15537             {
   15538                 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
   15539             }
   15540 
   15541             PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15542             PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
   15543 
   15544             if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR
   15545                     || iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR)
   15546             {
   15547                 if (!iCmdToDlaCancel.empty())
   15548                 {
   15549                     PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
   15550                     iCurrentCmd.erase(iCurrentCmd.begin());
   15551                     iCurrentCmd.push_front(iCmdToDlaCancel[0]);
   15552                     /* If we get here the command isn't queued so the cancel fails */
   15553                     EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg));
   15554                     iCurrentCmd.push_front(currentcmd);
   15555                     iCmdToDlaCancel.erase(iCmdToDlaCancel.begin());
   15556                 }
   15557                 else
   15558                 {
   15559                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeCancelGetLicense() ASSERT"));
   15560                     OSCL_ASSERT(false);
   15561                 }
   15562             }
   15563             else if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE)
   15564             {
   15565                 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg));
   15566             }
   15567             else
   15568             {
   15569                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeCancelGetLicense() ASSERT"));
   15570                 OSCL_ASSERT(false);
   15571             }
   15572             errmsg->removeRef();
   15573         }
   15574         break;
   15575     }
   15576 }
   15577 
   15578 void PVPlayerEngine::HandleSourceNodeErrorEvent(const PVMFAsyncEvent& aEvent)
   15579 {
   15580     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() In"));
   15581 
   15582     if (iState == PVP_ENGINE_STATE_RESETTING)
   15583     {
   15584         //this means error handling, reset or cancelall is still in progress
   15585         //no need to look for error event
   15586         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15587                         (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Return engine in resetting state no need to process the error event"));
   15588         return;
   15589     }
   15590 
   15591     for (uint32 i = 0; i < iCurrentContextList.size(); ++i)
   15592     {
   15593         if (iCurrentContextList[i]->iNode)
   15594         {
   15595             if (iCurrentContextList[i]->iNode == iSourceNode)
   15596             {
   15597                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15598                                 (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Cmd Pending on Source node, so src node should not send error events - ignoring err event"));
   15599                 return;
   15600             }
   15601         }
   15602     }
   15603 
   15604     PVMFEventType event = aEvent.GetEventType();
   15605 
   15606     switch (event)
   15607     {
   15608         case PVMFErrCorrupt:
   15609         case PVMFErrOverflow:
   15610         case PVMFErrResource:
   15611         case PVMFErrProcessing:
   15612         {
   15613             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15614                             (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Sending PVPlayerErrSourceMediaData for error event %d, Add EH command if not present", event));
   15615             bool ehPending = CheckForPendingErrorHandlingCmd();
   15616             if (ehPending)
   15617             {
   15618                 // there should be no error handling queued.
   15619                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Already EH pending, should never happen"));
   15620                 return;
   15621             }
   15622             else
   15623             {
   15624                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15625                 if (aEvent.GetEventExtensionInterface() != NULL)
   15626                 {
   15627                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15628                 }
   15629                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15630                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceMediaData, puuid, nextmsg));
   15631                 iCommandCompleteStatusInErrorHandling = event;
   15632                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15633                 if (iCurrentCmd.empty())
   15634                 {
   15635                     // this error was received when no cmd was being processed so send the error event from here
   15636                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15637                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15638                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15639                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15640                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15641                 }
   15642             }
   15643         }
   15644         break;
   15645 
   15646         case PVMFErrUnderflow:
   15647         {
   15648             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15649                             (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Sending PVPlayerErrSourceMediaDataUnavailable for error event %d, Add EH command if not present", event));
   15650             bool ehPending = CheckForPendingErrorHandlingCmd();
   15651             if (ehPending)
   15652             {
   15653                 // there should be no error handling queued.
   15654                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Already EH pending, should never happen"));
   15655                 return;
   15656             }
   15657             else
   15658             {
   15659                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15660                 if (aEvent.GetEventExtensionInterface() != NULL)
   15661                 {
   15662                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15663                 }
   15664                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15665                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceMediaDataUnavailable, puuid, nextmsg));
   15666                 iCommandCompleteStatusInErrorHandling = event;
   15667                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15668                 if (iCurrentCmd.empty())
   15669                 {
   15670                     // this error was received when no cmd was being processed so send the error event from here
   15671                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15672                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15673                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15674                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15675                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15676                 }
   15677             }
   15678         }
   15679         break;
   15680 
   15681         case PVMFErrNoResources:
   15682         case PVMFErrResourceConfiguration:
   15683         case PVMFErrTimeout:
   15684         case PVMFErrNoMemory:
   15685         {
   15686             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15687                             (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Sending PVPlayerErrSourceFatal for error event %d, Add EH command if not present", event));
   15688             bool ehPending = CheckForPendingErrorHandlingCmd();
   15689             if (ehPending)
   15690             {
   15691                 // there should be no error handling queued.
   15692                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Already EH pending, should never happen"));
   15693                 return;
   15694             }
   15695             else
   15696             {
   15697                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15698                 if (aEvent.GetEventExtensionInterface() != NULL)
   15699                 {
   15700                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15701                 }
   15702                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15703                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
   15704                 iCommandCompleteStatusInErrorHandling = event;
   15705                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15706                 if (iCurrentCmd.empty())
   15707                 {
   15708                     // this error was received when no cmd was being processed so send the error event from here
   15709                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15710                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15711                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15712                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15713                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15714                 }
   15715             }
   15716         }
   15717         break;
   15718 
   15719         default:
   15720             // Do nothing but log it
   15721             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Do nothing for this event %d", event));
   15722             break;
   15723     }
   15724 
   15725     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Out"));
   15726 }
   15727 
   15728 
   15729 void PVPlayerEngine::HandleDecNodeErrorEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
   15730 {
   15731     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() In"));
   15732 
   15733     OSCL_UNUSED_ARG(aDatapathIndex);
   15734 
   15735     if (iState == PVP_ENGINE_STATE_RESETTING)
   15736     {
   15737         //this means error handling, reset or cancelall is still in progress
   15738         //no need to look for error event
   15739         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15740                         (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Return engine in resetting state no need to process the error event"));
   15741         return;
   15742     }
   15743 
   15744     PVMFEventType event = aEvent.GetEventType();
   15745 
   15746     switch (event)
   15747     {
   15748         case PVMFErrCorrupt:
   15749         case PVMFErrOverflow:
   15750         case PVMFErrUnderflow:
   15751         case PVMFErrProcessing:
   15752         {
   15753             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15754                             (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Sending PVPlayerErrDatapathMediaData for error event %d, Add EH command if not present", event));
   15755             bool ehPending = CheckForPendingErrorHandlingCmd();
   15756             if (ehPending)
   15757             {
   15758                 // there should be no error handling queued.
   15759                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Already EH pending, should never happen"));
   15760                 return;
   15761             }
   15762             else
   15763             {
   15764                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15765                 if (aEvent.GetEventExtensionInterface() != NULL)
   15766                 {
   15767                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15768                 }
   15769                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15770                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathMediaData, puuid, nextmsg));
   15771                 iCommandCompleteStatusInErrorHandling = event;
   15772                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15773                 if (iCurrentCmd.empty())
   15774                 {
   15775                     // this error was received when no cmd was being processed so send the error event from here
   15776                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15777                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15778                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15779                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15780                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15781                 }
   15782             }
   15783         }
   15784         break;
   15785 
   15786         case PVMFErrTimeout:
   15787         case PVMFErrNoResources:
   15788         case PVMFErrResourceConfiguration:
   15789         case PVMFErrResource:
   15790         case PVMFErrNoMemory:
   15791         {
   15792             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15793                             (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Sending PVPlayerErrDatapathFatal for error event %d, Add EH command if not present", event));
   15794             bool ehPending = CheckForPendingErrorHandlingCmd();
   15795             if (ehPending)
   15796             {
   15797                 // there should be no error handling queued.
   15798                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Already EH pending, should never happen"));
   15799                 return;
   15800             }
   15801             else
   15802             {
   15803                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15804                 if (aEvent.GetEventExtensionInterface() != NULL)
   15805                 {
   15806                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15807                 }
   15808                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15809                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
   15810                 iCommandCompleteStatusInErrorHandling = event;
   15811                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15812                 if (iCurrentCmd.empty())
   15813                 {
   15814                     // this error was received when no cmd was being processed so send the error event from here
   15815                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15816                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15817                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15818                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15819                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15820                 }
   15821             }
   15822         }
   15823         break;
   15824 
   15825         default:
   15826             // Do nothing but log it
   15827             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Do nothing for this event %d", event));
   15828             break;
   15829     }
   15830 
   15831     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Out"));
   15832 }
   15833 
   15834 
   15835 void PVPlayerEngine::HandleSinkNodeErrorEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
   15836 {
   15837     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() In"));
   15838 
   15839     OSCL_UNUSED_ARG(aDatapathIndex);
   15840 
   15841     if (iState == PVP_ENGINE_STATE_RESETTING)
   15842     {
   15843         //this means error handling, reset or cancelall is still in progress
   15844         //no need to look for error event
   15845         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15846                         (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Return engine in resetting state no need to process the error event"));
   15847         return;
   15848     }
   15849 
   15850     PVMFEventType event = aEvent.GetEventType();
   15851 
   15852     switch (event)
   15853     {
   15854         case PVMFErrCorrupt:
   15855         case PVMFErrOverflow:
   15856         case PVMFErrUnderflow:
   15857         case PVMFErrProcessing:
   15858         {
   15859             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15860                             (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Sending PVPlayerErrDatapathMediaData for error event %d, Add EH command if not present", event));
   15861             bool ehPending = CheckForPendingErrorHandlingCmd();
   15862             if (ehPending)
   15863             {
   15864                 // there should be no error handling queued.
   15865                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Already EH pending, should never happen"));
   15866                 return;
   15867             }
   15868             else
   15869             {
   15870                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15871                 if (aEvent.GetEventExtensionInterface() != NULL)
   15872                 {
   15873                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15874                 }
   15875                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15876                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkMediaData, puuid, nextmsg));
   15877                 iCommandCompleteStatusInErrorHandling = event;
   15878                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15879                 if (iCurrentCmd.empty())
   15880                 {
   15881                     // this error was received when no cmd was being processed so send the error event from here
   15882                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15883                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15884                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15885                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15886                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15887                 }
   15888             }
   15889         }
   15890         break;
   15891 
   15892         case PVMFErrTimeout:
   15893         case PVMFErrNoResources:
   15894         case PVMFErrResourceConfiguration:
   15895         case PVMFErrResource:
   15896         case PVMFErrNoMemory:
   15897         {
   15898             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   15899                             (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Sending PVPlayerErrSinkFatal for error event %d, Add EH command if not present", event));
   15900             bool ehPending = CheckForPendingErrorHandlingCmd();
   15901             if (ehPending)
   15902             {
   15903                 // there should be no error handling queued.
   15904                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Already EH pending, should never happen"));
   15905                 return;
   15906             }
   15907             else
   15908             {
   15909                 PVMFErrorInfoMessageInterface* nextmsg = NULL;
   15910                 if (aEvent.GetEventExtensionInterface() != NULL)
   15911                 {
   15912                     nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   15913                 }
   15914                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   15915                 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkFatal, puuid, nextmsg));
   15916                 iCommandCompleteStatusInErrorHandling = event;
   15917                 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
   15918                 if (iCurrentCmd.empty())
   15919                 {
   15920                     // this error was received when no cmd was being processed so send the error event from here
   15921                     SendErrorEvent(iCommandCompleteStatusInErrorHandling,
   15922                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
   15923                                    aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   15924                     iCommandCompleteErrMsgInErrorHandling->removeRef();
   15925                     iCommandCompleteErrMsgInErrorHandling = NULL;
   15926                 }
   15927             }
   15928         }
   15929         break;
   15930 
   15931         default:
   15932             // Do nothing but log it
   15933             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Do nothing for this event %d", event));
   15934             break;
   15935     }
   15936 
   15937     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Out"));
   15938 }
   15939 
   15940 //Return val: true means found/deleted cmd(s).
   15941 bool PVPlayerEngine::removeCmdFromQ(Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> &aVec, const PVPlayerEngineCommandType aCmdType, bool aRemove)
   15942 {
   15943     if (aVec.size() == 0)
   15944     {
   15945         return false;
   15946     }
   15947     // OSCL priority queue doesn't allow index access so will need to
   15948     // go through each pending cmd one-by-one, save commands that are not auto-resume
   15949     // and put the commands back into the pending queue.
   15950     // Vector to hold the pending cmds temporarily
   15951     bool ret = false;
   15952     Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> tmpvec;
   15953     tmpvec.reserve(aVec.size());
   15954     tmpvec.clear();
   15955     // Go through each pending command
   15956 
   15957     for (int i = aVec.size() - 1; i >= 0; i--)
   15958     {
   15959         if (aVec[i].GetCmdType() == aCmdType)
   15960         {
   15961             ret = true;
   15962             if (!aRemove)
   15963             {
   15964                 return ret;
   15965             }
   15966             continue;
   15967         }
   15968         tmpvec.push_back(aVec[i]);
   15969     }
   15970     aVec.clear();
   15971     // Put the pending commands back in the priqueue
   15972     while (tmpvec.empty() == false)
   15973     {
   15974         aVec.push_front(tmpvec[0]);
   15975         tmpvec.erase(tmpvec.begin());
   15976     }
   15977     return ret;
   15978 }
   15979 
   15980 //Return val: true means found/deleted cmd(s).
   15981 bool PVPlayerEngine::removeCmdFromQ(OsclPriorityQueue<PVPlayerEngineCommand, OsclMemAllocator, Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator>, PVPlayerEngineCommandCompareLess> &aVec, const PVPlayerEngineCommandType aCmdType, bool aRemove)
   15982 {
   15983     // OSCL priority queue doesn't allow index access so will need to
   15984     // go through each pending cmd one-by-one, save commands that are not auto-resume
   15985     // and put the commands back into the pending queue.
   15986     // Vector to hold the pending cmds temporarily
   15987     bool ret = false;
   15988     Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> tmpvec;
   15989     tmpvec.reserve(aVec.size());
   15990     tmpvec.clear();
   15991     // Go through each pending command
   15992     while (aVec.empty() == false)
   15993     {
   15994         if (aVec.top().GetCmdType() == aCmdType)
   15995         {
   15996             ret = true;
   15997             if (!aRemove)
   15998             {
   15999                 return ret;
   16000             }
   16001             aVec.pop();
   16002             continue;
   16003         }
   16004         tmpvec.push_back(aVec.top());
   16005         aVec.pop();
   16006     }
   16007     // Put the pending commands back in the priqueue
   16008     while (tmpvec.empty() == false)
   16009     {
   16010         aVec.push(tmpvec[0]);
   16011         tmpvec.erase(tmpvec.begin());
   16012     }
   16013     return ret;
   16014 }
   16015 
   16016 void PVPlayerEngine::HandleSourceNodeInfoEvent(const PVMFAsyncEvent& aEvent)
   16017 {
   16018     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() In"));
   16019 
   16020     if (iState == PVP_ENGINE_STATE_RESETTING)
   16021     {
   16022         //this means error handling, reset or cancelall is still in progress
   16023         //no need to look for info event
   16024         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   16025                         (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Return engine in resetting state no need to process the info event %d", aEvent.GetEventType()));
   16026         return;
   16027     }
   16028 
   16029     PVMFEventType event = aEvent.GetEventType();
   16030 
   16031     switch (event)
   16032     {
   16033         case PVMFInfoBufferingStart:
   16034         case PVMFInfoBufferingComplete:
   16035         case PVMFInfoOverflow:
   16036         {
   16037             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending buffering event %d", event));
   16038             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16039         }
   16040         break;
   16041 
   16042         case PVMFInfoBufferingStatus:
   16043         {
   16044             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending buffering status event %d", event));
   16045             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16046         }
   16047         break;
   16048 
   16049         case PVMFInfoUnderflow:
   16050         {
   16051             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received PVMFInfoUnderflow"));
   16052             // remove pending auto-resume if there is any
   16053             if (removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, true))
   16054             {
   16055                 //cancelled the pending auto-resume
   16056                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() PVMFInfoUnderflow got cancelled"));
   16057                 break;
   16058             }
   16059 
   16060             // if no auto-pause in the queue and no auto-pause in progress, add one
   16061             if ((! removeCmdFromQ(iCurrentCmd, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, false))
   16062                     && (! removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, false)))
   16063             {
   16064                 AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, NULL, NULL, NULL, false);
   16065                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received source underflow event, issue auto-pause command"));
   16066             }
   16067         }
   16068         break;
   16069 
   16070         case PVMFInfoDataReady:
   16071         {
   16072             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received PVMFInfoDataReady"));
   16073             // remove pending auto-pause if there is any
   16074             if (removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, true))
   16075             {
   16076                 //cancelled the pending auto-pause
   16077                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() PVMFInfoDataReady got cancelled"));
   16078                 break;
   16079             }
   16080 
   16081             // if no resume in the queue and no resume in progress, add one
   16082             if ((! removeCmdFromQ(iCurrentCmd, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, false))
   16083                     && (! removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, false)))
   16084             {
   16085                 AddCommandToQueue(PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, NULL, NULL, NULL, false);
   16086                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received source data ready event, issue auto-resume command"));
   16087             }
   16088         }
   16089         break;
   16090 
   16091         case PVMFInfoContentLength:
   16092         case PVMFInfoContentType:
   16093         case PVMFInfoContentTruncated:
   16094         case PVMFInfoRemoteSourceNotification:
   16095         case PVMFInfoPlayListClipTransition:
   16096         case PVMFInfoPlayListSwitch:
   16097         {
   16098             PVInterface* intf = NULL;
   16099             PVMFBasicErrorInfoMessage* infomsg = NULL;
   16100             PVMFErrorInfoMessageInterface* nextmsg = NULL;
   16101             if (aEvent.GetEventExtensionInterface() != NULL)
   16102             {
   16103                 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
   16104                 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   16105                 infomsg =
   16106                     OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoSourceMediaData,
   16107                                                          puuid,
   16108                                                          nextmsg));
   16109                 intf = OSCL_STATIC_CAST(PVInterface*, infomsg);
   16110             }
   16111             SendInformationalEvent(event, intf, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16112             if (infomsg != NULL)
   16113             {
   16114                 infomsg->removeRef();
   16115             }
   16116             infomsg = NULL;
   16117         }
   16118         break;
   16119 
   16120         case PVMFInfoTrackDisable:
   16121         {
   16122             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending bad track disabled event %d", event));
   16123             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16124         }
   16125         break;
   16126 
   16127         case PVMFInfoUnexpectedData:
   16128         {
   16129             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending unexpected data event %d", event));
   16130             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16131         }
   16132         break;
   16133 
   16134         case PVMFInfoSessionDisconnect:
   16135         {
   16136             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending session disconnect %d", event));
   16137             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16138         }
   16139         break;
   16140         case PVMFInfoMetadataAvailable:
   16141         {
   16142             PVUuid infomsguuid = PVMFMetadataInfoMessageInterfaceUUID;
   16143             PVMFMetadataInfoMessageInterface* eventMsg = NULL;
   16144             PVInterface* infoExtInterface = aEvent.GetEventExtensionInterface();
   16145             if (infoExtInterface &&
   16146                     infoExtInterface->queryInterface(infomsguuid, (PVInterface*&)eventMsg))
   16147             {
   16148                 PVUuid eventuuid;
   16149                 int32 infoCode;
   16150                 eventMsg->GetCodeUUID(infoCode, eventuuid);
   16151                 if (eventuuid == infomsguuid)
   16152                 {
   16153                     Oscl_Vector<PvmiKvp, OsclMemAllocator> kvpVector = eventMsg->GetMetadataVector();
   16154                     SendInformationalEvent(aEvent.GetEventType(), infoExtInterface, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16155                 }
   16156             }
   16157         }
   16158         break;
   16159         case PVMFInfoDurationAvailable:
   16160         {
   16161             PVUuid infomsguuid = PVMFDurationInfoMessageInterfaceUUID;
   16162             PVMFDurationInfoMessageInterface* eventMsg = NULL;
   16163             PVInterface* infoExtInterface = aEvent.GetEventExtensionInterface();
   16164             PVInterface* temp = NULL;
   16165             if (infoExtInterface &&
   16166                     infoExtInterface->queryInterface(infomsguuid, temp))
   16167             {
   16168                 PVUuid eventuuid;
   16169                 int32 infoCode;
   16170                 eventMsg = OSCL_STATIC_CAST(PVMFDurationInfoMessageInterface*, temp);
   16171                 eventMsg->GetCodeUUID(infoCode, eventuuid);
   16172                 if (eventuuid == infomsguuid)
   16173                 {
   16174                     iSourceDurationInMS = eventMsg->GetDuration();
   16175                     iSourceDurationAvailable = true;
   16176                     SendInformationalEvent(aEvent.GetEventType(), infoExtInterface, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16177                 }
   16178             }
   16179             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending duration available %d", event));
   16180         }
   16181         break;
   16182 
   16183         case PVMFInfoPoorlyInterleavedContent:
   16184         {
   16185             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending Poorly Interleaved Content Info %d", event));
   16186             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16187         }
   16188         break;
   16189         case PVMFInfoSourceOverflow:
   16190         {
   16191             PVPPlaybackPosition aBeginPos;
   16192             aBeginPos.iIndeterminate = false;
   16193             aBeginPos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
   16194             aBeginPos.iPosValue.millisec_value = 0;
   16195             PVPPlaybackPosition aEndPos;
   16196             aEndPos.iIndeterminate = true;
   16197             iOverflowFlag = true;
   16198             SetPlaybackRange(aBeginPos, aEndPos, false);
   16199             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received source overflow event, issue auto-reposition command"));
   16200         }
   16201         break;
   16202         case PVMFInfoEndOfData:
   16203         default:
   16204             // Do nothing but log it
   16205             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Do nothing for this event %d", event));
   16206             break;
   16207     }
   16208 
   16209     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Out"));
   16210 }
   16211 
   16212 
   16213 void PVPlayerEngine::HandleDecNodeInfoEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
   16214 {
   16215     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() In"));
   16216 
   16217     if (iState == PVP_ENGINE_STATE_RESETTING)
   16218     {
   16219         //this means error handling, reset or cancelall is still in progress
   16220         //no need to look for info event
   16221         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   16222                         (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Return engine in resetting state no need to process the info event %d", aEvent.GetEventType()));
   16223         return;
   16224     }
   16225 
   16226     OSCL_UNUSED_ARG(aDatapathIndex);
   16227 
   16228     PVMFEventType event = aEvent.GetEventType();
   16229 
   16230     switch (event)
   16231     {
   16232         case PVMFInfoProcessingFailure:
   16233 
   16234             SendInformationalEvent(PVMFInfoProcessingFailure);
   16235             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Report ProcessingFailure event %d", event));
   16236             break;
   16237 
   16238         case PVMFInfoOverflow:
   16239         case PVMFInfoEndOfData:
   16240         default:
   16241             // Do nothing but log it
   16242             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Do nothing for this event %d", event));
   16243             break;
   16244     }
   16245 
   16246     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Out"));
   16247 }
   16248 
   16249 
   16250 void PVPlayerEngine::HandleSinkNodeInfoEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
   16251 {
   16252     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() In"));
   16253 
   16254     if (iState == PVP_ENGINE_STATE_RESETTING)
   16255     {
   16256         //this means error handling, reset or cancelall is still in progress
   16257         //no need to look for info event
   16258         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   16259                         (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Return engine in resetting state no need to process the info event %d", aEvent.GetEventType()));
   16260         return;
   16261     }
   16262 
   16263     PVMFEventType event = aEvent.GetEventType();
   16264 
   16265     switch (event)
   16266     {
   16267         case PVMFInfoStartOfData:
   16268         {
   16269             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoStartOfData event received for %s",
   16270                             iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr()));
   16271 
   16272             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoStartOfData event received for %s, iNumPendingSkipCompleteEvent=%d iNumPVMFInfoStartOfDataPending=%d",
   16273                             iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr(),
   16274                             iNumPendingSkipCompleteEvent, iNumPVMFInfoStartOfDataPending));
   16275 
   16276             uint32 *data = (uint32*) aEvent.GetEventData();
   16277             uint32 streamID = *data;
   16278 
   16279             if (streamID != iStreamID)
   16280             {
   16281                 // received StartOfData for previous streamId, ignoring these events
   16282                 break;
   16283             }
   16284 
   16285             if (iNumPVMFInfoStartOfDataPending > 0)
   16286             {
   16287                 --iNumPVMFInfoStartOfDataPending;
   16288             }
   16289 
   16290             if ((iNumPendingSkipCompleteEvent == 0) && (iNumPVMFInfoStartOfDataPending == 0))
   16291             {
   16292                 if (iWatchDogTimer->IsBusy())
   16293                 {
   16294                     iWatchDogTimer->Cancel();
   16295                 }
   16296                 //check engine internal state here prior to starting the clock
   16297                 //this is to make sure that we do not start the clock in case engine is still
   16298                 //auto-paused (think usecase: auto-pause, setplaybackrange, auto-resume)
   16299                 if (iState == PVP_ENGINE_STATE_STARTED)
   16300                 {
   16301                     // start the clock only if engine is in started state
   16302                     StartPlaybackClock();
   16303                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() - PlayClock Started"));
   16304                 }
   16305             }
   16306             //else it could mean duplicate or old PVMFInfoStartOfData, ignore both
   16307         }
   16308         break;
   16309         case PVMFInfoEndOfData:
   16310         {
   16311             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoEndOfData event received for %s",
   16312                             iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr()));
   16313 
   16314             uint32 *data = (uint32*) aEvent.GetEventData();
   16315             uint32 streamID = *data;
   16316 
   16317             if (streamID != iStreamID)
   16318             {
   16319                 // received EndOfData for previous streamId, ignoring these events
   16320                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoEndOfData event received for %s with StreamID=%d, Engine StreamID=%d",
   16321                                 iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr(),
   16322                                 streamID, iStreamID));
   16323                 break;
   16324             }
   16325 
   16326             if (iDatapathList[aDatapathIndex].iDatapath && iDatapathList[aDatapathIndex].iEndOfDataReceived == false)
   16327             {
   16328                 iDatapathList[aDatapathIndex].iEndOfDataReceived = true;
   16329                 // If all datapath received EOS, initiate a pause-due-to-EOS
   16330                 if (AllDatapathReceivedEndOfData() == true)
   16331                 {
   16332                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Issue Pause due to end of clip"));
   16333                     AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP, NULL, NULL, NULL, false);
   16334                 }
   16335             }
   16336             else
   16337             {
   16338                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoEndOfData event received for non-active or already-ended datapath. Asserting"));
   16339                 OSCL_ASSERT(false);
   16340             }
   16341         }
   16342         break;
   16343 
   16344         case PVMFInfoDataDiscarded:
   16345             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoDataDiscarded event received"));
   16346             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16347             break;
   16348 
   16349         case PVMFInfoVideoTrackFallingBehind:
   16350             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoVideoTrackFallingBehind event received"));
   16351             SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
   16352             break;
   16353 
   16354         default:
   16355             // Do nothing but log it
   16356             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Do nothing for this event %d", event));
   16357             break;
   16358     }
   16359 
   16360     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Out"));
   16361 }
   16362 
   16363 
   16364 bool PVPlayerEngine::AllDatapathReceivedEndOfData()
   16365 {
   16366     // Return false if any active datapath hasn't
   16367     // received EOS yet. Else true.
   16368     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   16369     {
   16370         if (iDatapathList[i].iDatapath &&
   16371                 iDatapathList[i].iEndOfDataReceived == false)
   16372         {
   16373             return false;
   16374         }
   16375     }
   16376 
   16377     return true;
   16378 }
   16379 
   16380 
   16381 void PVPlayerEngine::SendEndOfClipInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
   16382 {
   16383     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndOfClipInfoEvent() In"));
   16384 
   16385     // If paused succeeded or already paused
   16386     if (aStatus == PVMFSuccess || aStatus == PVMFErrInvalidState)
   16387     {
   16388         // Set the flag so we can disable resume unless user stops, repositions, or changes directrion
   16389         iPlaybackPausedDueToEndOfClip = true;
   16390 
   16391         PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   16392         PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoEndOfClipReached, puuid, NULL));
   16393         SendInformationalEvent(PVMFInfoEndOfData, OSCL_STATIC_CAST(PVInterface*, infomsg));
   16394         infomsg->removeRef();
   16395     }
   16396     else
   16397     {
   16398         SendErrorEvent(aStatus, aExtInterface);
   16399     }
   16400 
   16401     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndOfClipInfoEvent() Out"));
   16402 }
   16403 
   16404 
   16405 void PVPlayerEngine::SendEndTimeReachedInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
   16406 {
   16407     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndTimeReachedInfoEvent() In"));
   16408 
   16409     if (aStatus == PVMFSuccess)
   16410     {
   16411         PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
   16412         PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoEndTimeReached, puuid, NULL));
   16413         SendInformationalEvent(PVMFInfoEndOfData, OSCL_STATIC_CAST(PVInterface*, infomsg));
   16414         infomsg->removeRef();
   16415     }
   16416     else
   16417     {
   16418         SendErrorEvent(aStatus, aExtInterface);
   16419     }
   16420 
   16421     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndTimeReachedInfoEvent() Out"));
   16422 }
   16423 
   16424 
   16425 void PVPlayerEngine::SendSourceUnderflowInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
   16426 {
   16427     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceUnderflowInfoEvent() In"));
   16428 
   16429     if (aStatus == PVMFSuccess || aStatus == PVMFErrNotSupported)
   16430     {
   16431         if (iDataReadySent)
   16432         {
   16433             iDataReadySent = false;
   16434             SendInformationalEvent(PVMFInfoUnderflow);
   16435         }
   16436     }
   16437     else if (aStatus == PVMFErrCancelled)
   16438     {
   16439         // Do nothing since the auto-pause was cancelled
   16440     }
   16441     else
   16442     {
   16443         SendErrorEvent(aStatus, aExtInterface);
   16444     }
   16445 
   16446     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceUnderflowInfoEvent() Out"));
   16447 }
   16448 
   16449 
   16450 void PVPlayerEngine::SendSourceDataReadyInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
   16451 {
   16452     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceDataReadyInfoEvent() In"));
   16453 
   16454 
   16455     if (aStatus == PVMFSuccess || aStatus == PVMFErrNotSupported)
   16456     {
   16457         // send DataReady event only if it is not sent earlier and if EOS is not reported.
   16458         // It is possible that for Streaming repositioning to end use-cases engine receives
   16459         // EOS before prepare completes, in that case suppress DataReady event.
   16460         if (!iDataReadySent && !iPlaybackPausedDueToEndOfClip)
   16461         {
   16462             iDataReadySent = true;
   16463             SendInformationalEvent(PVMFInfoDataReady);
   16464         }
   16465     }
   16466     else if (aStatus == PVMFErrCancelled)
   16467     {
   16468         // Do nothing since the auto-resume was cancelled
   16469     }
   16470     else
   16471     {
   16472         SendErrorEvent(aStatus, aExtInterface);
   16473     }
   16474 
   16475     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceDataReadyInfoEvent() Out"));
   16476 }
   16477 
   16478 
   16479 PVMFErrorInfoMessageInterface* PVPlayerEngine::GetErrorInfoMessageInterface(PVInterface& aInterface)
   16480 {
   16481     PVMFErrorInfoMessageInterface* extiface = NULL;
   16482     PVInterface* temp = NULL;
   16483     if (aInterface.queryInterface(PVMFErrorInfoMessageInterfaceUUID, temp))
   16484     {
   16485         extiface = OSCL_STATIC_CAST(PVMFErrorInfoMessageInterface*, temp);
   16486         return extiface;
   16487     }
   16488     else
   16489     {
   16490         return NULL;
   16491     }
   16492 }
   16493 
   16494 
   16495 void PVPlayerEngine::StartPlaybackStatusTimer(void)
   16496 {
   16497     // Check if playback position reporting is enabled
   16498     if (!iPBPosEnable || iPlayStatusTimerEnabled)
   16499         return;
   16500     // To get regular play status events
   16501     iPlayStatusTimerEnabled = true;
   16502 
   16503     iClockNotificationsInf->SetCallbackDeltaTime(iPBPosStatusInterval,
   16504             iPlayStatusCallbackTimerMarginWindow, (PVMFMediaClockNotificationsObs*)this, false, NULL,
   16505             iPlayStatusCallbackTimerID);
   16506 }
   16507 
   16508 
   16509 void PVPlayerEngine::StopPlaybackStatusTimer(void)
   16510 {
   16511 
   16512     // Stop the playback position status timer
   16513     iPlayStatusTimerEnabled = false;
   16514     if (iClockNotificationsInf && iPlayStatusCallbackTimerID)
   16515     {
   16516         iClockNotificationsInf->CancelCallback(iPlayStatusCallbackTimerID, false);
   16517         iPlayStatusCallbackTimerID = 0;
   16518     }
   16519 }
   16520 
   16521 bool PVPlayerEngine::CheckForSourceRollOver()
   16522 {
   16523     uint32 alternates = iDataSource->GetNumAlternateSourceFormatTypes();
   16524     if ((alternates > 0) && (iAlternateSrcFormatIndex < alternates))
   16525     {
   16526         return true;
   16527     }
   16528     return false;
   16529 }
   16530 
   16531 PVMFStatus PVPlayerEngine::SetupDataSourceForUnknownURLAccess()
   16532 {
   16533     if (iDataSource == NULL)
   16534     {
   16535         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - No Data Source"));
   16536         return PVMFErrInvalidState;
   16537     }
   16538     else
   16539     {
   16540         /*
   16541          * In case of unknown url, here is the sequence that engine would attempt:
   16542          *  1) First Alternate source format would be PVMF_DATA_SOURCE_RTSP_URL,
   16543          *  implying that we would attempt a RTSP streaming session
   16544          *
   16545          *  2) Primary source format would be set to PVMF_DATA_SOURCE_HTTP_URL,
   16546          *  implying that we would attempt a progressive download first.
   16547          *
   16548          *  3) Second Alternate source format would be PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL,
   16549          *  implying that we would attempt a real media cloaking session
   16550          *
   16551          *  4) Third alternate source format would be PVMF_DATA_SOURCE_MS_HTTP_STREAMING_URL,
   16552          *  implying that we would attempt a MS HTTP streaming session
   16553          */
   16554         iSourceFormatType = PVMF_MIME_DATA_SOURCE_RTSP_URL; ;
   16555         if (iDataSource->SetAlternateSourceFormatType(PVMF_MIME_DATA_SOURCE_HTTP_URL) != true)
   16556         {
   16557             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - SetAlternateSourceFormatType Failed"));
   16558             return PVMFFailure;
   16559         }
   16560         if (iDataSource->SetAlternateSourceFormatType(PVMF_MIME_DATA_SOURCE_REAL_HTTP_CLOAKING_URL) != true)
   16561         {
   16562             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - SetAlternateSourceFormatType Failed"));
   16563             return PVMFFailure;
   16564         }
   16565         if (iDataSource->SetAlternateSourceFormatType(PVMF_MIME_DATA_SOURCE_MS_HTTP_STREAMING_URL) != true)
   16566         {
   16567             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - SetAlternateSourceFormatType Failed"));
   16568             return PVMFFailure;
   16569         }
   16570         return PVMFSuccess;
   16571     }
   16572 }
   16573 
   16574 /* scan thru aKvpValue, create a new PvmiKvp object and push
   16575  * than onto iPvmiKvpCapNConfig.
   16576  *  return PVMFSuccess unless allocation error
   16577  */
   16578 PVMFStatus PVPlayerEngine:: VerifyAndSaveKVPValues(PvmiKvp *aKvpValue)
   16579 {
   16580 
   16581     PvmiKvp* KvpCapNConfig = (PvmiKvp *)OSCL_MALLOC(sizeof(PvmiKvp));
   16582     if (! KvpCapNConfig)  return PVMFErrNoMemory;
   16583     oscl_memcpy(KvpCapNConfig, aKvpValue, sizeof(PvmiKvp));
   16584 
   16585 
   16586     KvpCapNConfig->key = (char*)OSCL_MALLOC(oscl_strlen(aKvpValue->key) + 1);
   16587     if (! KvpCapNConfig->key)  return PVMFErrNoMemory;
   16588     oscl_strncpy(KvpCapNConfig->key, aKvpValue->key, oscl_strlen(aKvpValue->key) + 1);
   16589 
   16590 
   16591     // all the values have copied automatically so just need to allocate memory of pointer type.
   16592 
   16593     if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=wchar*")) != NULL)
   16594     {
   16595         KvpCapNConfig->value.pWChar_value = (oscl_wchar*)OSCL_MALLOC((oscl_strlen(aKvpValue->value.pWChar_value) + 1) * sizeof(oscl_wchar));
   16596         if (! KvpCapNConfig->value.pWChar_value)  return PVMFErrNoMemory;
   16597         oscl_strncpy(KvpCapNConfig->value.pWChar_value, aKvpValue->value.pWChar_value, oscl_strlen(aKvpValue->value.pWChar_value) + 1);
   16598 
   16599     }
   16600     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=char*")) != NULL)
   16601     {
   16602         KvpCapNConfig->value.pChar_value = (char*)OSCL_MALLOC(oscl_strlen(aKvpValue->value.pChar_value) + 1);
   16603         if (! KvpCapNConfig->value.pChar_value)  return PVMFErrNoMemory;
   16604         oscl_strncpy(KvpCapNConfig->value.pChar_value, aKvpValue->value.pChar_value, oscl_strlen(aKvpValue->value.pChar_value) + 1);
   16605 
   16606     }
   16607     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=uint8*")) != NULL)
   16608     {
   16609         KvpCapNConfig->value.pUint8_value = (uint8*)OSCL_MALLOC(oscl_strlen((char *)aKvpValue->value.pUint8_value) + 1);
   16610         if (! KvpCapNConfig->value.pUint8_value)  return PVMFErrNoMemory;
   16611         oscl_memcpy(KvpCapNConfig->value.pUint8_value, aKvpValue->value.pUint8_value, oscl_strlen((char *)aKvpValue->value.pUint8_value) + 1);
   16612 
   16613     }
   16614     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=int32*")) != NULL)
   16615     {
   16616         KvpCapNConfig->value.pInt32_value = (int32*)OSCL_MALLOC(sizeof(int32));
   16617         if (! KvpCapNConfig->value.pInt32_value)  return PVMFErrNoMemory;
   16618         oscl_memcpy(KvpCapNConfig->value.pInt32_value, aKvpValue->value.pInt32_value, sizeof(int32));
   16619         // @TODO: Future support will be based on length , currently support only one element
   16620     }
   16621     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=uint32*")) != NULL)
   16622     {
   16623         KvpCapNConfig->value.pUint32_value = (uint32*)OSCL_MALLOC(sizeof(uint32));
   16624         if (! KvpCapNConfig->value.pUint32_value)  return PVMFErrNoMemory;
   16625         oscl_memcpy(KvpCapNConfig->value.pUint32_value, aKvpValue->value.pUint32_value, sizeof(uint32));
   16626         // @TODO: Future support will be based on length, currently support only one element
   16627     }
   16628     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=int64*")) != NULL)
   16629     {
   16630         KvpCapNConfig->value.pInt64_value = (int64*)OSCL_MALLOC(sizeof(int64));
   16631         if (! KvpCapNConfig->value.pInt64_value)  return PVMFErrNoMemory;
   16632         oscl_memcpy(KvpCapNConfig->value.pInt64_value, aKvpValue->value.pInt64_value, sizeof(int64));
   16633         // @TODO: Future support will be based on length, currently support only one element
   16634     }
   16635     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=uint64*")) != NULL)
   16636     {
   16637         KvpCapNConfig->value.pUint64_value = (uint64*)OSCL_MALLOC(sizeof(uint64));
   16638         if (! KvpCapNConfig->value.pUint64_value)  return PVMFErrNoMemory;
   16639         oscl_memcpy(KvpCapNConfig->value.pUint64_value, aKvpValue->value.pUint64_value, sizeof(uint64));
   16640         // @TODO: Future support will be based on length, currently support only one element
   16641     }
   16642     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=float*")) != NULL)
   16643     {
   16644         KvpCapNConfig->value.pFloat_value = (float*)OSCL_MALLOC(sizeof(float));
   16645         if (! KvpCapNConfig->value.pFloat_value)  return PVMFErrNoMemory;
   16646         oscl_memcpy(KvpCapNConfig->value.pFloat_value, aKvpValue->value.pFloat_value, sizeof(float));
   16647         // @TODO: Future support will be based on length, currently support only one element
   16648     }
   16649     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=double*")) != NULL)
   16650     {
   16651         KvpCapNConfig->value.pDouble_value = (double*)OSCL_MALLOC(sizeof(double));
   16652         if (! KvpCapNConfig->value.pDouble_value)  return PVMFErrNoMemory;
   16653         oscl_memcpy(KvpCapNConfig->value.pDouble_value, aKvpValue->value.pDouble_value, sizeof(double));
   16654         // @TODO: Future support will be based on length, currently support only one element
   16655     }
   16656     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=range_int32")) != NULL)
   16657     {
   16658         KvpCapNConfig->value.key_specific_value = (void*)OSCL_MALLOC(sizeof(range_int32));
   16659         if (! KvpCapNConfig->value.key_specific_value)  return PVMFErrNoMemory;
   16660         oscl_memcpy(KvpCapNConfig->value.key_specific_value, aKvpValue->value.key_specific_value, sizeof(range_int32));
   16661         // @TODO: Future support will be based on length, currently support only one element
   16662     }
   16663     else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=range_uint32")) != NULL)
   16664     {
   16665         KvpCapNConfig->value.key_specific_value = (void*)OSCL_MALLOC(sizeof(range_uint32));
   16666         if (! KvpCapNConfig->value.key_specific_value)  return PVMFErrNoMemory;
   16667         oscl_memcpy(KvpCapNConfig->value.key_specific_value, aKvpValue->value.key_specific_value, sizeof(range_uint32));
   16668         // @TODO: Future support will be based on length, currently support only one element
   16669     }
   16670 
   16671     iPvmiKvpCapNConfig.push_back(KvpCapNConfig);
   16672     return PVMFSuccess;
   16673 }
   16674 
   16675 
   16676 void PVPlayerEngine::SetRollOverKVPValues()
   16677 {
   16678     PvmiKvp *SaveKvp;
   16679     PvmiKvp *ErrorKVP;
   16680 
   16681     for (uint i = 0; i < iPvmiKvpCapNConfig.size(); i++)
   16682     {
   16683         SaveKvp = iPvmiKvpCapNConfig[i];
   16684         setParametersSync(NULL, SaveKvp, 1 , ErrorKVP);
   16685 
   16686         if (ErrorKVP != NULL)
   16687         {
   16688             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetRollOverKVPValues() Configuring cap-config failed"));
   16689         }
   16690     }
   16691 
   16692 }
   16693 
   16694 void PVPlayerEngine::DeleteKVPValues()
   16695 {
   16696     uint i = 0;
   16697     while (i < iPvmiKvpCapNConfig.size())
   16698     {
   16699         PvmiKvp **Setkvp = iPvmiKvpCapNConfig.begin();
   16700 
   16701         if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=wchar*")) != NULL)
   16702         {
   16703             OSCL_FREE((*Setkvp)->value.pWChar_value);
   16704             (*Setkvp)->value.pWChar_value = NULL;
   16705 
   16706         }
   16707         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=char*")) != NULL)
   16708         {
   16709             OSCL_FREE((*Setkvp)->value.pChar_value);
   16710             (*Setkvp)->value.pChar_value = NULL;
   16711         }
   16712         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=uint8*")) != NULL)
   16713         {
   16714             OSCL_FREE((*Setkvp)->value.pUint8_value);
   16715             (*Setkvp)->value.pUint8_value = NULL;
   16716         }
   16717 
   16718         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=int32*")) != NULL)
   16719         {
   16720             OSCL_FREE((*Setkvp)->value.pInt32_value);
   16721             (*Setkvp)->value.pInt32_value = NULL;
   16722 
   16723         }
   16724         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=uint32*")) != NULL)
   16725         {
   16726             OSCL_FREE((*Setkvp)->value.pUint32_value);
   16727             (*Setkvp)->value.pUint32_value = NULL;
   16728 
   16729         }
   16730         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=int64*")) != NULL)
   16731         {
   16732             OSCL_FREE((*Setkvp)->value.pInt64_value);
   16733             (*Setkvp)->value.pInt64_value = NULL;
   16734 
   16735         }
   16736         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=uint64*")) != NULL)
   16737         {
   16738             OSCL_FREE((*Setkvp)->value.pUint64_value);
   16739             (*Setkvp)->value.pUint64_value = NULL;
   16740         }
   16741         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=float*")) != NULL)
   16742         {
   16743             OSCL_FREE((*Setkvp)->value.pFloat_value);
   16744             (*Setkvp)->value.pFloat_value = NULL;
   16745         }
   16746         else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=double*")) != NULL)
   16747         {
   16748             OSCL_FREE((*Setkvp)->value.pDouble_value);
   16749             (*Setkvp)->value.pDouble_value = NULL;
   16750         }
   16751         else if ((oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=range_int32")) != NULL) ||
   16752                  (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=range_uint32")) != NULL))
   16753         {
   16754             OSCL_FREE((*Setkvp)->value.key_specific_value);
   16755             (*Setkvp)->value.key_specific_value = NULL;
   16756         }
   16757 
   16758         OSCL_FREE((*Setkvp)->key);
   16759         (*Setkvp)->key = NULL;
   16760 
   16761         OSCL_FREE(*Setkvp);
   16762         *Setkvp = NULL;
   16763 
   16764         iPvmiKvpCapNConfig.erase(iPvmiKvpCapNConfig.begin());
   16765     }
   16766 
   16767 }
   16768 
   16769 
   16770 void PVPlayerEngine::PVPlayerWatchdogTimerEvent()
   16771 {
   16772     //check engine internal state here prior to starting the clock
   16773     //this is to make sure that we do not start the clock in case engine is still
   16774     //auto-paused (think usecase: auto-pause, setplaybackrange, auto-resume)
   16775     if (iState == PVP_ENGINE_STATE_STARTED)
   16776     {
   16777         // start the clock only if engine is in started state
   16778         StartPlaybackClock();
   16779         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::PVPlayerWatchdogTimerEvent() WatchDog timer expired"));
   16780         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::PVPlayerWatchdogTimerEvent() WatchDog timer expired"));
   16781     }
   16782 }
   16783 
   16784 void PVPlayerEngine::StartPlaybackClock()
   16785 {
   16786     if (iWatchDogTimer->IsBusy())
   16787     {
   16788         iWatchDogTimer->Cancel();
   16789     }
   16790 
   16791     if (iPlaybackClock.GetState() == PVMFMediaClock::RUNNING)
   16792     {
   16793         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "PVPlayerEngine::StartPlaybackClock() clock already started"));
   16794         return;
   16795     }
   16796 
   16797     iPlaybackClock.Start();
   16798     // Notify all sink nodes that have sync control IF that clock has started
   16799     for (uint32 i = 0; i < iDatapathList.size(); ++i)
   16800     {
   16801         if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
   16802         {
   16803             iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
   16804         }
   16805     }
   16806 
   16807     // To get regular play status events
   16808     StartPlaybackStatusTimer();
   16809 
   16810     // Restart the end time check if enabled
   16811     if (iEndTimeCheckEnabled)
   16812     {
   16813         // Determine the check cycle based on interval setting in milliseconds
   16814         // and timer frequency of 100 millisec
   16815         int32 checkcycle = iEndTimeCheckInterval / 100;
   16816         if (checkcycle == 0)
   16817         {
   16818             ++checkcycle;
   16819         }
   16820         iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
   16821         iPollingCheckTimer->Request(PVPLAYERENGINE_TIMERID_ENDTIMECHECK, 0, checkcycle, this, true);
   16822     }
   16823 
   16824     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::StartPlaybackClock() StartNPT %d StartTS %d", iStartNPT, iStartMediaDataTS));
   16825 }
   16826 
   16827 PVMFStatus PVPlayerEngine::GetCompleteList(PVMFMediaPresentationInfo& aList)
   16828 {
   16829     if (iSourceNodeTrackSelIF)
   16830     {
   16831         PVPlayerState state = GetPVPlayerState();
   16832         if ((state == PVP_STATE_INITIALIZED) ||
   16833                 (state == PVP_STATE_PREPARED) ||
   16834                 (state == PVP_STATE_STARTED) ||
   16835                 (state == PVP_STATE_PAUSED))
   16836         {
   16837             aList.Reset();
   16838             PVMFStatus retval = PVMFFailure;
   16839             int32 leavecode = 0;
   16840             OSCL_TRY(leavecode, retval = iSourceNodeTrackSelIF->GetMediaPresentationInfo(aList));
   16841             OSCL_FIRST_CATCH_ANY(leavecode,
   16842                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetCompleteList() GetMediaPresentationInfo on iSourceNodeTrackSelIF did a leave!"));
   16843                                  return PVMFFailure);
   16844             if (retval != PVMFSuccess)
   16845             {
   16846                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetCompleteList() GetMediaPresentationInfo() call on source node failed"));
   16847             }
   16848             return retval;
   16849         }
   16850     }
   16851     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetCompleteList() iSourceNodeTrackSelIF Invalid"));
   16852     return PVMFFailure;
   16853 }
   16854 
   16855 PVMFStatus PVPlayerEngine::ReleaseCompleteList(PVMFMediaPresentationInfo& aList)
   16856 {
   16857     aList.Reset();
   16858     return PVMFSuccess;
   16859 }
   16860 
   16861 PVMFStatus PVPlayerEngine::GetPlayableList(PVMFMediaPresentationInfo& aList)
   16862 {
   16863     PVPlayerState state = GetPVPlayerState();
   16864     if ((state == PVP_STATE_PREPARED) ||
   16865             (state == PVP_STATE_STARTED) ||
   16866             (state == PVP_STATE_PAUSED))
   16867     {
   16868         aList = iPlayableList;
   16869         if (aList.getNumTracks() == 0)
   16870         {
   16871             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetPlayableList() No tracks"));
   16872             return PVMFFailure;
   16873         }
   16874         return PVMFSuccess;
   16875     }
   16876     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetPlayableList() Invalid Engine State"));
   16877     return PVMFErrInvalidState;
   16878 }
   16879 
   16880 PVMFStatus PVPlayerEngine::ReleasePlayableList(PVMFMediaPresentationInfo& aList)
   16881 {
   16882     aList.Reset();
   16883     return PVMFSuccess;
   16884 }
   16885 
   16886 PVMFStatus PVPlayerEngine::GetSelectedList(PVMFMediaPresentationInfo& aList)
   16887 {
   16888     PVPlayerState state = GetPVPlayerState();
   16889     if ((state == PVP_STATE_PREPARED) ||
   16890             (state == PVP_STATE_STARTED) ||
   16891             (state == PVP_STATE_PAUSED))
   16892     {
   16893         aList.Reset();
   16894         aList.setPresentationType(iPlayableList.getPresentationType());
   16895         aList.setSeekableFlag(iPlayableList.IsSeekable());
   16896         aList.SetDurationAvailable(iPlayableList.IsDurationAvailable());
   16897         aList.setDurationValue(iPlayableList.getDurationValue());
   16898         aList.setDurationTimeScale(iPlayableList.getDurationTimeScale());
   16899         for (uint32 i = 0; i < iDatapathList.size(); ++i)
   16900         {
   16901             if (iDatapathList[i].iTrackInfo != NULL)
   16902             {
   16903                 aList.addTrackInfo(*(iDatapathList[i].iTrackInfo));
   16904             }
   16905         }
   16906         if (aList.getNumTracks() == 0)
   16907         {
   16908             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetSelectedList() No tracks"));
   16909             return PVMFFailure;
   16910         }
   16911         return PVMFSuccess;
   16912     }
   16913     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetSelectedList() Invalid Engine State"));
   16914     return PVMFErrInvalidState;
   16915 }
   16916 
   16917 PVMFStatus PVPlayerEngine::ReleaseSelectedList(PVMFMediaPresentationInfo& aList)
   16918 {
   16919     aList.Reset();
   16920     return PVMFSuccess;
   16921 }
   16922 
   16923 PVMFStatus PVPlayerEngine::RegisterHelperObject(PVMFTrackSelectionHelper* aObject)
   16924 {
   16925     if (aObject != NULL)
   16926     {
   16927         if (iTrackSelectionHelper != NULL)
   16928         {
   16929             return PVMFErrAlreadyExists;
   16930         }
   16931     }
   16932     iTrackSelectionHelper = aObject;
   16933     return PVMFSuccess;
   16934 }
   16935 
   16936 void PVPlayerEngine::ResetReposVariables(bool aResetAll)
   16937 {
   16938     if (aResetAll)
   16939     {
   16940         iStreamID = 0;
   16941     }
   16942     if (iWatchDogTimer != NULL)
   16943     {
   16944         if (iWatchDogTimer->IsBusy())
   16945         {
   16946             iWatchDogTimer->Cancel();
   16947         }
   16948     }
   16949     iNumPendingSkipCompleteEvent = 0;
   16950     iNumPVMFInfoStartOfDataPending = 0;
   16951     iTargetNPT = 0;
   16952     iActualNPT = 0;
   16953     iActualMediaDataTS = 0;
   16954     iSkipMediaDataTS = 0;
   16955 }
   16956 
   16957 PVMFStatus PVPlayerEngine::DoErrorHandling()
   16958 {
   16959     //pls note that we come into this method twice, in case of error handling
   16960     //first time, we come here to start the error handling seq (cancelall if any, followed by reset)
   16961     //second time, we come here when all resets are complete to cleanup and send command completes
   16962     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoErrorHandling() In"));
   16963     // Stop the playback clock
   16964     iPlaybackClock.Stop();
   16965 
   16966     // 1st check if anything needs to be cancelled on Source Node or Datapaths
   16967     if (!iCurrentContextList.empty())
   16968     {
   16969         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   16970                         (0, "PVPlayerEngine::DoErrorHandling() Some Command is being processed, cancel it"));
   16971         for (uint32 i = 0; i < iCurrentContextList.size(); ++i)
   16972         {
   16973             if (iCurrentContextList[i]->iNode)
   16974             {
   16975                 if (iCurrentContextList[i]->iNode == iSourceNode)
   16976                 {
   16977                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoErrorHandling() Cmd Pending on Source node, should never happend, asserting"));
   16978                     OSCL_ASSERT(false);
   16979                 }
   16980             }
   16981         }
   16982 
   16983         // error handling code set engine state to resetting
   16984         SetEngineState(PVP_ENGINE_STATE_RESETTING);
   16985         iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
   16986         // Since there is a pending node or datapath, cancel it
   16987         PVMFStatus status = DoCancelPendingNodeDatapathCommand();
   16988         if (status == PVMFPending)
   16989         {
   16990             // There are some commands which need to be cancelled so wait for cancel complete
   16991             // once cancels complete, we would start the reset sequence from either
   16992             // NodeCommandComplete, HandlePlayerDataPathEvent, RecognizeComplete
   16993             return PVMFPending;
   16994         }
   16995         // if there is nothing to cancel move forward to reset.
   16996     }
   16997 
   16998     // move on to resetting Source Nodes and Datapaths
   16999     if (iSourceNode)
   17000     {
   17001         int32 leavecode = 0;
   17002         // call reset on source node if not in created state
   17003         if (iSourceNode->GetState() != EPVMFNodeCreated)
   17004         {
   17005             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   17006                             (0, "PVPlayerEngine::DoErrorHandling() Issue reset on Source Node"));
   17007             // error handling code set engine state to resetting
   17008             SetEngineState(PVP_ENGINE_STATE_RESETTING);
   17009             iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
   17010 
   17011             PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
   17012 
   17013             PVMFCommandId cmdid = -1;
   17014             leavecode = 0;
   17015             OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
   17016             OSCL_FIRST_CATCH_ANY(leavecode,
   17017 
   17018                                  PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   17019                                                  (0, "PVPlayerEngine::DoErrorHandling() Reset on iSourceNode did a leave!"));
   17020                                  FreeEngineContext(context);
   17021                                  OSCL_ASSERT(false);
   17022                                  return PVMFFailure);
   17023 
   17024             return PVMFPending;
   17025         }
   17026     }
   17027 
   17028     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   17029                     (0, "PVPlayerEngine::DoErrorHandling() Source node is deleted or in created state, so start removing sinks"));
   17030 
   17031     // Now delete the datapath.
   17032     DoRemoveAllSinks();
   17033 
   17034     // finally do the source node cleanup
   17035     if (iDataSource)
   17036     {
   17037         RemoveDataSourceSync(*iDataSource);
   17038     }
   17039 
   17040     SetEngineState(PVP_ENGINE_STATE_IDLE);
   17041 
   17042     // Send the command completion if there is any command in Current command
   17043     if (!iCurrentCmd.empty())
   17044     {
   17045         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
   17046                         (0, "PVPlayerEngine::DoErrorHandling() Complete the engine command being processed"));
   17047         if (iCommandCompleteErrMsgInErrorHandling)
   17048         {
   17049             EngineCommandCompleted(iCurrentCmd[0].GetCmdId(),
   17050                                    iCurrentCmd[0].GetContext(),
   17051                                    iCommandCompleteStatusInErrorHandling,
   17052                                    OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling));
   17053             iCommandCompleteErrMsgInErrorHandling->removeRef();
   17054             iCommandCompleteErrMsgInErrorHandling = NULL;
   17055         }
   17056         else
   17057         {
   17058             EngineCommandCompleted(iCurrentCmd[0].GetCmdId(),
   17059                                    iCurrentCmd[0].GetContext(),
   17060                                    iCommandCompleteStatusInErrorHandling);
   17061         }
   17062     }
   17063 
   17064     // just send the error handling complete event
   17065     SendInformationalEvent(PVMFInfoErrorHandlingComplete, NULL);
   17066 
   17067     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoErrorHandling() Out"));
   17068 
   17069     return PVMFSuccess;
   17070 }
   17071 
   17072 bool PVPlayerEngine::CheckForPendingErrorHandlingCmd()
   17073 {
   17074     //if an error handling cmd had been queued previously
   17075     //it must be in top, since error handling cmds have the
   17076     //highest priority and pending cmds queue is a priority
   17077     //queue
   17078     bool retval = false;
   17079     if (!iPendingCmds.empty())
   17080     {
   17081         switch (iPendingCmds.top().GetCmdType())
   17082         {
   17083             case PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE:
   17084             case PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT:
   17085             case PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE:
   17086             case PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE:
   17087             case PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME:
   17088             case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE:
   17089             case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE:
   17090             case PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP:
   17091             case PVP_ENGINE_COMMAND_ERROR_HANDLING_CANCEL_ALL_COMMANDS:
   17092             case PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL:
   17093                 retval = true;
   17094                 break;
   17095 
   17096             default:
   17097                 break;
   17098         }
   17099     }
   17100     return retval;
   17101 }
   17102 
   17103 PVMFStatus PVPlayerEngine::IssueNodeCancelCommand(PVPlayerEngineContext* aCurrentListContext, PVMFSessionId aSessionId, OsclAny* aNumberCancelCmdPending)
   17104 {
   17105     PVMFStatus leavecode = 0;
   17106     OSCL_TRY(leavecode, aCurrentListContext->iNode->CancelAllCommands(aSessionId, aNumberCancelCmdPending));
   17107     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17108     return leavecode;
   17109 }
   17110 
   17111 PVMFStatus PVPlayerEngine::IssueDatapathCancelCommand(PVPlayerEngineContext* aCurrentListContext, OsclAny* aNumberCancelCmdPending)
   17112 {
   17113     PVMFStatus leavecode = 0;
   17114     OSCL_TRY(leavecode, aCurrentListContext->iDatapath->CancelCommand(aNumberCancelCmdPending));
   17115     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17116     return leavecode;
   17117 }
   17118 
   17119 PVMFStatus PVPlayerEngine::IssueRecognizerRegistryCancel(OsclAny* aNumberCancelCmdPending)
   17120 {
   17121     PVMFStatus leavecode = 0;
   17122     OSCL_TRY(leavecode, iPlayerRecognizerRegistry.CancelQuery(aNumberCancelCmdPending));
   17123     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17124     return leavecode;
   17125 }
   17126 
   17127 PVMFStatus PVPlayerEngine::IssueSinkNodeInit(PVPlayerEngineDatapath* aDatapath, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
   17128 {
   17129     PVMFStatus leavecode = 0;
   17130     OSCL_TRY(leavecode, aCmdId = aDatapath->iSinkNode->Init(aDatapath->iSinkNodeSessionId, aCmdContext));
   17131     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17132     return leavecode;
   17133 }
   17134 
   17135 PVMFStatus PVPlayerEngine::IssueSinkNodeReset(PVPlayerEngineDatapath* aDatapath, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
   17136 {
   17137     PVMFStatus leavecode = 0;
   17138     OSCL_TRY(leavecode, aCmdId = aDatapath->iSinkNode->Reset(aDatapath->iSinkNodeSessionId, aCmdContext));
   17139     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17140     return leavecode;
   17141 }
   17142 
   17143 PVMFStatus PVPlayerEngine::IssueSinkSkipMediaData(PVPlayerEngineDatapath* aDatapath, bool aSFR, OsclAny* aCmdContext)
   17144 {
   17145     PVMFStatus leavecode = 0;
   17146     OSCL_TRY(leavecode, aDatapath->iSinkNodeSyncCtrlIF->SkipMediaData(aDatapath->iSinkNodeSessionId, iSkipMediaDataTS, iStreamID, aSFR, aCmdContext));
   17147     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17148     return leavecode;
   17149 }
   17150 
   17151 PVMFStatus PVPlayerEngine::IssueSourceSetDataSourcePosition(bool aIsPosUnitPlayList, OsclAny* aCmdContext)
   17152 {
   17153     PVMFStatus leavecode = 0;
   17154     if (aIsPosUnitPlayList)
   17155     {
   17156         OSCL_TRY(leavecode, iSourceNodePBCtrlIF->SetDataSourcePosition(iSourceNodeSessionId,
   17157                  iDataSourcePosParams,
   17158                  aCmdContext));
   17159 
   17160     }
   17161     else
   17162     {
   17163         OSCL_TRY(leavecode, iSourceNodePBCtrlIF->SetDataSourcePosition(iSourceNodeSessionId,
   17164                  iTargetNPT, iActualNPT, iActualMediaDataTS, iSeekToSyncPoint, iStreamID, aCmdContext));
   17165     }
   17166     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17167     return leavecode;
   17168 }
   17169 
   17170 PVMFStatus PVPlayerEngine::IssueDecNodeInit(PVMFNodeInterface* aNode, PVMFSessionId aDecNodeSessionId, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
   17171 {
   17172     PVMFStatus leavecode = 0;
   17173     OSCL_TRY(leavecode, aCmdId = aNode->Init(aDecNodeSessionId, aCmdContext));
   17174     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17175     return leavecode;
   17176 }
   17177 
   17178 PVMFStatus PVPlayerEngine::IssueDecNodeReset(PVMFNodeInterface* aNode, PVMFSessionId aDecNodeSessionId, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
   17179 {
   17180     PVMFStatus leavecode = 0;
   17181     OSCL_TRY(leavecode, aCmdId = aNode->Reset(aDecNodeSessionId, aCmdContext));
   17182     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17183     return leavecode;
   17184 }
   17185 
   17186 PVMFStatus PVPlayerEngine::IssueQueryInterface(PVMFNodeInterface* aNode, PVMFSessionId aSessionId, const PVUuid aUuid, PVInterface*& aInterfacePtr, OsclAny* aCmdContext, PVMFCommandId& aCmdId)
   17187 {
   17188     PVMFStatus leavecode = 0;
   17189     OSCL_TRY(leavecode, aCmdId = aNode->QueryInterface(aSessionId, aUuid, aInterfacePtr, aCmdContext));
   17190     OSCL_FIRST_CATCH_ANY(leavecode,;);
   17191     return leavecode;
   17192 }
   17193 
   17194 OSCL_EXPORT_REF void
   17195 PVPlayerInterface::GetSDKInfo
   17196 (
   17197     PVSDKInfo& aSdkInfo
   17198 )
   17199 {
   17200     aSdkInfo.iLabel = PVPLAYER_ENGINE_SDKINFO_LABEL;
   17201     aSdkInfo.iDate  = PVPLAYER_ENGINE_SDKINFO_DATE;
   17202 }
   17203 
   17204 // END FILE
   17205 
   17206 
   17207 
   17208 
   17209 
   17210 
   17211 
   17212 
   17213 
   17214 
   17215 
   17216 
   17217