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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec, &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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 340 return DoGetPVPlayerState(cmd, true); 341 } 342 else 343 { 344 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE_OOTSYNC, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 491 } 492 else 493 { 494 return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE, (OsclAny*)aContextData, ¶mvec, 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 540 return DoGetCurrentPosition(cmd, true); 541 } 542 else 543 { 544 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION_OOTSYNC, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 820 821 // Complete the request synchronously 822 DoCapConfigSetParameters(cmd, true); 823 } 824 else 825 { 826 DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS_OOTSYNC, ¶mvec); 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, ¶mvec, 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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, ¶mvec); 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(¶mkvp[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 = ¶mkvp[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 = ¶mkvp[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 = ¶mkvp[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 = ¶mkvp[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 = ¶mkvp[paramind]; 10262 bool anysuccess = false; 10263 10264 10265 if (iSourceNodeCapConfigIF != NULL) 10266 { 10267 *retkvp = NULL; 10268 iSourceNodeCapConfigIF->setParametersSync(NULL, ¶mkvp[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, ¶mkvp[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, ¶mkvp[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 = ¶mkvp[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