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,