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
New(PVCommandStatusObserver * aCmdStatusObserver,PVErrorEventObserver * aErrorEventObserver,PVInformationalEventObserver * aInfoEventObserver)97 PVPlayerEngine* PVPlayerEngine::New(PVCommandStatusObserver* aCmdStatusObserver,
98 PVErrorEventObserver *aErrorEventObserver,
99 PVInformationalEventObserver *aInfoEventObserver)
100 {
101 PVPlayerEngine* engine = NULL;
102 engine = OSCL_NEW(PVPlayerEngine, ());
103 if (engine)
104 {
105 engine->Construct(aCmdStatusObserver,
106 aErrorEventObserver,
107 aInfoEventObserver);
108 }
109
110 return engine;
111 }
112
113
~PVPlayerEngine()114 PVPlayerEngine::~PVPlayerEngine()
115 {
116 Cancel();
117
118 // Clear the Track selection List
119 iTrackSelectionList.clear();
120
121 // Remove Stored KVP Values
122 DeleteKVPValues();
123
124 if (!iPendingCmds.empty())
125 {
126 iPendingCmds.pop();
127 }
128
129 // Clean up the datapaths
130 for (uint32 i = 0; i < iDatapathList.size(); ++i)
131 {
132 DoEngineDatapathCleanup(iDatapathList[i]);
133 }
134 iDatapathList.clear();
135
136 // Clean up the source node
137 DoSourceNodeCleanup();
138
139 // Shutdown and destroy the timer
140 if (iPollingCheckTimer)
141 {
142 iPollingCheckTimer->Clear();
143 }
144
145 if (iWatchDogTimer)
146 {
147 iWatchDogTimer->Cancel();
148 OSCL_DELETE(iWatchDogTimer);
149 }
150
151 OSCL_DELETE(iPollingCheckTimer);
152
153 //Destroy media clock notifications interface
154 if (iClockNotificationsInf != NULL)
155 {
156 iPlaybackClock.DestroyMediaClockNotificationsInterface(iClockNotificationsInf);
157 iClockNotificationsInf = NULL;
158 }
159
160 // Return all engine contexts to pool
161 while (!iCurrentContextList.empty())
162 {
163 FreeEngineContext(iCurrentContextList[0]);
164 }
165
166 PVPlayerRegistryPopulator::Depopulate(iPlayerNodeRegistry, iPlayerRecognizerRegistry);
167
168 iNodeUuids.clear();
169
170 iCommandIdMut.Close();
171 iOOTSyncCommandSem.Close();
172 }
173
174
GetSDKInfo(PVSDKInfo & aSDKInfo,const OsclAny * aContextData)175 PVCommandId PVPlayerEngine::GetSDKInfo(PVSDKInfo &aSDKInfo, const OsclAny* aContextData)
176 {
177 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetSDKInfo()"));
178 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
179 paramvec.reserve(1);
180 paramvec.clear();
181 PVPlayerEngineCommandParamUnion param;
182 param.pOsclAny_value = (OsclAny*) & aSDKInfo;
183 paramvec.push_back(param);
184 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_SDK_INFO, (OsclAny*)aContextData, ¶mvec);
185 }
186
187
GetSDKModuleInfo(PVSDKModuleInfo & aSDKModuleInfo,const OsclAny * aContextData)188 PVCommandId PVPlayerEngine::GetSDKModuleInfo(PVSDKModuleInfo &aSDKModuleInfo, const OsclAny* aContextData)
189 {
190 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetSDKModuleInfo()"));
191 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
192 paramvec.reserve(1);
193 paramvec.clear();
194 PVPlayerEngineCommandParamUnion param;
195 param.pOsclAny_value = (OsclAny*) & aSDKModuleInfo;
196 paramvec.push_back(param);
197 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_SDK_MODULE_INFO, (OsclAny*)aContextData, ¶mvec);
198 }
199
200
SetLogAppender(const char * aTag,OsclSharedPtr<PVLoggerAppender> & aAppender,const OsclAny * aContextData)201 PVCommandId PVPlayerEngine::SetLogAppender(const char* aTag, OsclSharedPtr<PVLoggerAppender>& aAppender, const OsclAny* aContextData)
202 {
203 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetLogAppender()"));
204 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
205 paramvec.reserve(2);
206 paramvec.clear();
207 PVPlayerEngineCommandParamUnion param;
208 param.pChar_value = (char*)aTag;
209 paramvec.push_back(param);
210 param.pOsclAny_value = (OsclAny*) & aAppender;
211 paramvec.push_back(param);
212 return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_LOG_APPENDER, (OsclAny*)aContextData, ¶mvec);
213 }
214
215
RemoveLogAppender(const char * aTag,OsclSharedPtr<PVLoggerAppender> & aAppender,const OsclAny * aContextData)216 PVCommandId PVPlayerEngine::RemoveLogAppender(const char* aTag, OsclSharedPtr<PVLoggerAppender>& aAppender, const OsclAny* aContextData)
217 {
218 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveLogAppender()"));
219 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
220 paramvec.reserve(2);
221 paramvec.clear();
222 PVPlayerEngineCommandParamUnion param;
223 param.pChar_value = (char*)aTag;
224 paramvec.push_back(param);
225 param.pOsclAny_value = (OsclAny*) & aAppender;
226 paramvec.push_back(param);
227 return AddCommandToQueue(PVP_ENGINE_COMMAND_REMOVE_LOG_APPENDER, (OsclAny*)aContextData, ¶mvec);
228 }
229
230
SetLogLevel(const char * aTag,int32 aLevel,bool aSetSubtree,const OsclAny * aContextData)231 PVCommandId PVPlayerEngine::SetLogLevel(const char* aTag, int32 aLevel, bool aSetSubtree, const OsclAny* aContextData)
232 {
233 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetLogLevel()"));
234 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
235 paramvec.reserve(3);
236 paramvec.clear();
237 PVPlayerEngineCommandParamUnion param;
238 param.pChar_value = (char*)aTag;
239 paramvec.push_back(param);
240 param.int32_value = aLevel;
241 paramvec.push_back(param);
242 param.bool_value = aSetSubtree;
243 paramvec.push_back(param);
244 return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_LOG_LEVEL, (OsclAny*)aContextData, ¶mvec);
245 }
246
247
GetLogLevel(const char * aTag,PVLogLevelInfo & aLogInfo,const OsclAny * aContextData)248 PVCommandId PVPlayerEngine::GetLogLevel(const char* aTag, PVLogLevelInfo& aLogInfo, const OsclAny* aContextData)
249 {
250 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetLogLevel()"));
251 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
252 paramvec.reserve(2);
253 paramvec.clear();
254 PVPlayerEngineCommandParamUnion param;
255 param.pChar_value = (char*)aTag;
256 paramvec.push_back(param);
257 param.pOsclAny_value = (OsclAny*) & aLogInfo;
258 paramvec.push_back(param);
259 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_LOG_LEVEL, (OsclAny*)aContextData, ¶mvec);
260 }
261
262
QueryUUID(const PvmfMimeString & aMimeType,Oscl_Vector<PVUuid,OsclMemAllocator> & aUuids,bool aExactUuidsOnly,const OsclAny * aContextData)263 PVCommandId PVPlayerEngine::QueryUUID(const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
264 bool aExactUuidsOnly, const OsclAny* aContextData)
265 {
266 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::QueryUUID()"));
267 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
268 paramvec.reserve(3);
269 paramvec.clear();
270 PVPlayerEngineCommandParamUnion param;
271 param.pOsclAny_value = (OsclAny*) & aMimeType;
272 paramvec.push_back(param);
273 param.pOsclAny_value = (OsclAny*) & aUuids;
274 paramvec.push_back(param);
275 param.bool_value = aExactUuidsOnly;
276 paramvec.push_back(param);
277 return AddCommandToQueue(PVP_ENGINE_COMMAND_QUERY_UUID, (OsclAny*)aContextData, ¶mvec);
278 }
279
280
QueryInterface(const PVUuid & aUuid,PVInterface * & aInterfacePtr,const OsclAny * aContextData)281 PVCommandId PVPlayerEngine::QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContextData)
282 {
283 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::QueryInterface()"));
284 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
285 paramvec.reserve(1);
286 paramvec.clear();
287 PVPlayerEngineCommandParamUnion param;
288 param.pOsclAny_value = (OsclAny*) & aInterfacePtr;
289 paramvec.push_back(param);
290 return AddCommandToQueue(PVP_ENGINE_COMMAND_QUERY_INTERFACE, (OsclAny*)aContextData, ¶mvec, &aUuid);
291 }
292
293
CancelCommand(PVCommandId aCancelCmdId,const OsclAny * aContextData)294 PVCommandId PVPlayerEngine::CancelCommand(PVCommandId aCancelCmdId, const OsclAny* aContextData)
295 {
296 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CancelCommand()"));
297 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
298 paramvec.reserve(1);
299 paramvec.clear();
300 PVPlayerEngineCommandParamUnion param;
301 param.int32_value = aCancelCmdId;
302 paramvec.push_back(param);
303 return AddCommandToQueue(PVP_ENGINE_COMMAND_CANCEL_COMMAND, (OsclAny*)aContextData, ¶mvec);
304 }
305
306
CancelAllCommands(const OsclAny * aContextData)307 PVCommandId PVPlayerEngine::CancelAllCommands(const OsclAny* aContextData)
308 {
309 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CancelAllCommands()"));
310 return AddCommandToQueue(PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS, (OsclAny*)aContextData);
311 }
312
313
GetPVPlayerState(PVPlayerState & aState,const OsclAny * aContextData)314 PVCommandId PVPlayerEngine::GetPVPlayerState(PVPlayerState& aState, const OsclAny* aContextData)
315 {
316 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPVPlayerState()"));
317 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
318 paramvec.reserve(1);
319 paramvec.clear();
320 PVPlayerEngineCommandParamUnion param;
321 param.pOsclAny_value = (OsclAny*) & aState;
322 paramvec.push_back(param);
323 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE, (OsclAny*)aContextData, ¶mvec);
324 }
325
326
GetPVPlayerStateSync(PVPlayerState & aState)327 PVMFStatus PVPlayerEngine::GetPVPlayerStateSync(PVPlayerState& aState)
328 {
329 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPVPlayerStateSync()"));
330 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
331 paramvec.reserve(1);
332 paramvec.clear();
333 PVPlayerEngineCommandParamUnion param;
334 param.pOsclAny_value = (OsclAny*) & aState;
335 paramvec.push_back(param);
336 if (iThreadSafeQueue.IsInThread())
337 {
338 PVPlayerEngineCommand cmd(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE, -1, NULL, ¶mvec);
339 return DoGetPVPlayerState(cmd, true);
340 }
341 else
342 {
343 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE_OOTSYNC, ¶mvec);
344 }
345 }
346
347
AddDataSource(PVPlayerDataSource & aDataSource,const OsclAny * aContextData)348 PVCommandId PVPlayerEngine::AddDataSource(PVPlayerDataSource& aDataSource, const OsclAny* aContextData)
349 {
350 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AddDataSource()"));
351 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
352 paramvec.reserve(1);
353 paramvec.clear();
354 PVPlayerEngineCommandParamUnion param;
355 param.pOsclAny_value = (OsclAny*) & aDataSource;
356 paramvec.push_back(param);
357 return AddCommandToQueue(PVP_ENGINE_COMMAND_ADD_DATA_SOURCE, (OsclAny*)aContextData, ¶mvec);
358 }
359
360
Init(const OsclAny * aContextData)361 PVCommandId PVPlayerEngine::Init(const OsclAny* aContextData)
362 {
363 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Init()"));
364 return AddCommandToQueue(PVP_ENGINE_COMMAND_INIT, (OsclAny*)aContextData);
365 }
366
367
GetMetadataKeys(PVPMetadataList & aKeyList,int32 aStartingIndex,int32 aMaxEntries,char * aQueryKey,const OsclAny * aContextData)368 PVCommandId PVPlayerEngine::GetMetadataKeys(PVPMetadataList& aKeyList, int32 aStartingIndex, int32 aMaxEntries,
369 char* aQueryKey, const OsclAny* aContextData)
370 {
371 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetMetadataKeys()"));
372 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
373 paramvec.reserve(4);
374 paramvec.clear();
375 PVPlayerEngineCommandParamUnion param;
376
377 param.pOsclAny_value = (OsclAny*) & aKeyList;
378 paramvec.push_back(param);
379 param.int32_value = aStartingIndex;
380 paramvec.push_back(param);
381 param.int32_value = aMaxEntries;
382 paramvec.push_back(param);
383 param.pChar_value = aQueryKey;
384 paramvec.push_back(param);
385
386 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_METADATA_KEY, (OsclAny*)aContextData, ¶mvec);
387 }
388
GetMetadataValues(PVPMetadataList & aKeyList,int32 aStartingValueIndex,int32 aMaxValueEntries,int32 & aNumAvailableValueEntries,Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList,const OsclAny * aContextData,bool aMetadataValuesCopiedInCallBack)389 PVCommandId PVPlayerEngine::GetMetadataValues(PVPMetadataList& aKeyList, int32 aStartingValueIndex, int32 aMaxValueEntries, int32& aNumAvailableValueEntries,
390 Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, const OsclAny* aContextData, bool aMetadataValuesCopiedInCallBack)
391 {
392 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetMetadataValues()"));
393 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
394 paramvec.reserve(6);
395 paramvec.clear();
396 PVPlayerEngineCommandParamUnion param;
397
398 param.pOsclAny_value = (OsclAny*) & aKeyList;
399 paramvec.push_back(param);
400 param.int32_value = aStartingValueIndex;
401 paramvec.push_back(param);
402 param.int32_value = aMaxValueEntries;
403 paramvec.push_back(param);
404 param.pOsclAny_value = (OsclAny*) & aNumAvailableValueEntries;
405 paramvec.push_back(param);
406 param.pOsclAny_value = (OsclAny*) & aValueList;
407 paramvec.push_back(param);
408 param.bool_value = aMetadataValuesCopiedInCallBack;
409 paramvec.push_back(param);
410
411 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_METADATA_VALUE, (OsclAny*)aContextData, ¶mvec);
412 }
413
ReleaseMetadataValues(Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList,const OsclAny * aContextData)414 PVCommandId PVPlayerEngine::ReleaseMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, const OsclAny* aContextData)
415 {
416 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ReleaseMetadataValues()"));
417 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
418 paramvec.reserve(1);
419 paramvec.clear();
420 PVPlayerEngineCommandParamUnion param;
421
422 param.pOsclAny_value = (OsclAny*) & aValueList;
423 paramvec.push_back(param);
424
425 return AddCommandToQueue(PVP_ENGINE_COMMAND_RELEASE_METADATA_VALUE, (OsclAny*)aContextData, ¶mvec);
426 }
427
AddDataSink(PVPlayerDataSink & aDataSink,const OsclAny * aContextData)428 PVCommandId PVPlayerEngine::AddDataSink(PVPlayerDataSink& aDataSink, const OsclAny* aContextData)
429 {
430 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AddDataSink()"));
431 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
432 paramvec.reserve(1);
433 paramvec.clear();
434 PVPlayerEngineCommandParamUnion param;
435 param.pOsclAny_value = (OsclAny*) & aDataSink;
436 paramvec.push_back(param);
437 return AddCommandToQueue(PVP_ENGINE_COMMAND_ADD_DATA_SINK, (OsclAny*)aContextData, ¶mvec);
438 }
439
440
SetPlaybackRange(PVPPlaybackPosition aBeginPos,PVPPlaybackPosition aEndPos,bool aQueueRange,const OsclAny * aContextData)441 PVCommandId PVPlayerEngine::SetPlaybackRange(PVPPlaybackPosition aBeginPos, PVPPlaybackPosition aEndPos, bool aQueueRange, const OsclAny* aContextData)
442 {
443 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetPlaybackRange()"));
444 PVPPlaybackPosition curpos;
445 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
446
447 // Additional checks to ensure a valid mode is
448 // used for the begin position.
449 // Assumes: aBegin.iPosUnit is always valid (when applicable).
450
451 // Check 1 || Check 2
452 // Check 1: Is the begin position indeterminate?
453 // Check 2: Is the position unit something other than playlist?
454 // If so, set mode to NOW.
455 if ((aBeginPos.iIndeterminate) || (aBeginPos.iPosUnit != PVPPBPOSUNIT_PLAYLIST))
456 {
457 aBeginPos.iMode = PVPPBPOS_MODE_NOW;
458 }
459 // Check 3: Is the position unit playlist and the mode something other than the three valid
460 // modes? If so, set mode to NOW.
461 else if (aBeginPos.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
462 {
463 switch (aBeginPos.iMode)
464 {
465 case PVPPBPOS_MODE_NOW:
466 case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT:
467 case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION:
468 break;
469 case PVPPBPOS_MODE_UNKNOWN:
470 default:
471 aBeginPos.iMode = PVPPBPOS_MODE_NOW;
472 break;
473 }
474 }
475 iPlaybackPositionMode = aBeginPos.iMode;
476 GetPlaybackClockPosition(curpos);
477 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
478 paramvec.reserve(3);
479 paramvec.clear();
480 PVPlayerEngineCommandParamUnion param;
481 param.playbackpos_value = aBeginPos;
482 paramvec.push_back(param);
483 param.playbackpos_value = aEndPos;
484 paramvec.push_back(param);
485 param.bool_value = aQueueRange;
486 paramvec.push_back(param);
487 if (!iOverflowFlag)
488 {
489 return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE, (OsclAny*)aContextData, ¶mvec);
490 }
491 else
492 {
493 return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE, (OsclAny*)aContextData, ¶mvec, NULL, false);
494 }
495 }
496
497
GetPlaybackRange(PVPPlaybackPosition & aBeginPos,PVPPlaybackPosition & aEndPos,bool aQueued,const OsclAny * aContextData)498 PVCommandId PVPlayerEngine::GetPlaybackRange(PVPPlaybackPosition &aBeginPos, PVPPlaybackPosition &aEndPos, bool aQueued, const OsclAny* aContextData)
499 {
500 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPlaybackRange()"));
501 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
502 paramvec.reserve(3);
503 paramvec.clear();
504 PVPlayerEngineCommandParamUnion param;
505 param.pPlaybackpos_value = &aBeginPos;
506 paramvec.push_back(param);
507 param.pPlaybackpos_value = &aEndPos;
508 paramvec.push_back(param);
509 param.bool_value = aQueued;
510 paramvec.push_back(param);
511 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PLAYBACK_RANGE, (OsclAny*)aContextData, ¶mvec);
512 }
513
514
GetCurrentPosition(PVPPlaybackPosition & aPos,const OsclAny * aContextData)515 PVCommandId PVPlayerEngine::GetCurrentPosition(PVPPlaybackPosition &aPos, const OsclAny* aContextData)
516 {
517 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetCurrentPosition()"));
518 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
519 paramvec.clear();
520 PVPlayerEngineCommandParamUnion param;
521 param.pPlaybackpos_value = &aPos;
522 paramvec.push_back(param);
523 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION, (OsclAny*)aContextData, ¶mvec);
524 }
525
526
GetCurrentPositionSync(PVPPlaybackPosition & aPos)527 PVMFStatus PVPlayerEngine::GetCurrentPositionSync(PVPPlaybackPosition &aPos)
528 {
529 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetCurrentPositionSync()"));
530 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
531 paramvec.reserve(1);
532 paramvec.clear();
533 PVPlayerEngineCommandParamUnion param;
534 param.pPlaybackpos_value = &aPos;
535 paramvec.push_back(param);
536 if (iThreadSafeQueue.IsInThread())
537 {
538 PVPlayerEngineCommand cmd(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION, -1, NULL, ¶mvec);
539 return DoGetCurrentPosition(cmd, true);
540 }
541 else
542 {
543 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION_OOTSYNC, ¶mvec);
544 }
545 }
546
547
SetPlaybackRate(int32 aRate,PVMFTimebase * aTimebase,const OsclAny * aContextData)548 PVCommandId PVPlayerEngine::SetPlaybackRate(int32 aRate, PVMFTimebase* aTimebase, const OsclAny* aContextData)
549 {
550 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetPlaybackRate()"));
551 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
552 paramvec.reserve(2);
553 paramvec.clear();
554 PVPlayerEngineCommandParamUnion param;
555 param.int32_value = aRate;
556 paramvec.push_back(param);
557 param.pOsclAny_value = (OsclAny*)aTimebase;
558 paramvec.push_back(param);
559 return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RATE, (OsclAny*)aContextData, ¶mvec);
560 }
561
562
GetPlaybackRate(int32 & aRate,PVMFTimebase * & aTimebase,const OsclAny * aContextData)563 PVCommandId PVPlayerEngine::GetPlaybackRate(int32& aRate, PVMFTimebase*& aTimebase, const OsclAny* aContextData)
564 {
565 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPlaybackRate()"));
566 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
567 paramvec.reserve(2);
568 paramvec.clear();
569 PVPlayerEngineCommandParamUnion param;
570 param.pInt32_value = &aRate;
571 paramvec.push_back(param);
572 param.pOsclAny_value = (OsclAny*) & aTimebase;
573 paramvec.push_back(param);
574 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PLAYBACK_RATE, (OsclAny*)aContextData, ¶mvec);
575 }
576
577
GetPlaybackMinMaxRate(int32 & aMinRate,int32 & aMaxRate,const OsclAny * aContextData)578 PVCommandId PVPlayerEngine::GetPlaybackMinMaxRate(int32& aMinRate, int32& aMaxRate, const OsclAny* aContextData)
579 {
580 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::GetPlaybackMinMaxRate()"));
581 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
582 paramvec.reserve(2);
583 paramvec.clear();
584 PVPlayerEngineCommandParamUnion param;
585 param.pInt32_value = &aMinRate;
586 paramvec.push_back(param);
587 param.pInt32_value = &aMaxRate;
588 paramvec.push_back(param);
589 return AddCommandToQueue(PVP_ENGINE_COMMAND_GET_PLAYBACK_MINMAX_RATE, (OsclAny*)aContextData, ¶mvec);
590 }
591
592
Prepare(const OsclAny * aContextData)593 PVCommandId PVPlayerEngine::Prepare(const OsclAny* aContextData)
594 {
595 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Prepare()"));
596 return AddCommandToQueue(PVP_ENGINE_COMMAND_PREPARE, (OsclAny*)aContextData);
597 }
598
599
Start(const OsclAny * aContextData)600 PVCommandId PVPlayerEngine::Start(const OsclAny* aContextData)
601 {
602 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Start() "));
603 return AddCommandToQueue(PVP_ENGINE_COMMAND_START, (OsclAny*)aContextData);
604 }
605
606
Pause(const OsclAny * aContextData)607 PVCommandId PVPlayerEngine::Pause(const OsclAny* aContextData)
608 {
609 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Pause()"));
610 return AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE, (OsclAny*)aContextData);
611 }
612
613
Resume(const OsclAny * aContextData)614 PVCommandId PVPlayerEngine::Resume(const OsclAny* aContextData)
615 {
616 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Resume()"));
617 return AddCommandToQueue(PVP_ENGINE_COMMAND_RESUME, (OsclAny*)aContextData);
618 }
619
620
Stop(const OsclAny * aContextData)621 PVCommandId PVPlayerEngine::Stop(const OsclAny* aContextData)
622 {
623 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Stop()"));
624 return AddCommandToQueue(PVP_ENGINE_COMMAND_STOP, (OsclAny*)aContextData);
625 }
626
627
RemoveDataSink(PVPlayerDataSink & aDataSink,const OsclAny * aContextData)628 PVCommandId PVPlayerEngine::RemoveDataSink(PVPlayerDataSink& aDataSink, const OsclAny* aContextData)
629 {
630 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSink()"));
631 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
632 paramvec.reserve(1);
633 paramvec.clear();
634 PVPlayerEngineCommandParamUnion param;
635 param.pOsclAny_value = (OsclAny*) & aDataSink;
636 paramvec.push_back(param);
637 return AddCommandToQueue(PVP_ENGINE_COMMAND_REMOVE_DATA_SINK, (OsclAny*)aContextData, ¶mvec);
638 }
639
640
Reset(const OsclAny * aContextData)641 PVCommandId PVPlayerEngine::Reset(const OsclAny* aContextData)
642 {
643 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Reset()"));
644 return AddCommandToQueue(PVP_ENGINE_COMMAND_RESET, (OsclAny*)aContextData);
645 }
646
647
RemoveDataSource(PVPlayerDataSource & aDataSource,const OsclAny * aContextData)648 PVCommandId PVPlayerEngine::RemoveDataSource(PVPlayerDataSource& aDataSource, const OsclAny* aContextData)
649 {
650 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSource()"));
651 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
652 paramvec.reserve(1);
653 paramvec.clear();
654 PVPlayerEngineCommandParamUnion param;
655 param.pOsclAny_value = (OsclAny*) & aDataSource;
656 paramvec.push_back(param);
657 return AddCommandToQueue(PVP_ENGINE_COMMAND_REMOVE_DATA_SOURCE, (OsclAny*)aContextData, ¶mvec);
658 }
659
660
setObserver(PvmiConfigAndCapabilityCmdObserver * aObserver)661 void PVPlayerEngine::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
662 {
663 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setObserver()"));
664
665 if (iThreadSafeQueue.IsInThread())
666 {
667 iCfgCapCmdObserver = aObserver;
668 }
669 else
670 {
671 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
672 paramvec.reserve(2);
673 paramvec.clear();
674 PVPlayerEngineCommandParamUnion param;
675 param.pOsclAny_value = aObserver;
676 paramvec.push_back(param);
677 DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_SET_OBSERVER_OOTSYNC, ¶mvec);
678 }
679 }
680
DoSetObserverSync(PVPlayerEngineCommand & aCmd)681 PVMFStatus PVPlayerEngine::DoSetObserverSync(PVPlayerEngineCommand& aCmd)
682 {
683 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetObserverSync() In"));
684
685 iCfgCapCmdObserver = (PvmiConfigAndCapabilityCmdObserver*)(aCmd.GetParam(0).pOsclAny_value);
686
687 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetObserverSync() Out"));
688 return PVMFSuccess;
689 }
690
getParametersSync(PvmiMIOSession aSession,PvmiKeyType aIdentifier,PvmiKvp * & aParameters,int & aNumParamElements,PvmiCapabilityContext aContext)691 PVMFStatus PVPlayerEngine::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
692 {
693 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::getParametersSync()"));
694 OSCL_UNUSED_ARG(aSession);
695
696 if (iThreadSafeQueue.IsInThread())
697 {
698 return DoCapConfigGetParametersSync(aIdentifier, aParameters, aNumParamElements, aContext);
699 }
700 else
701 {
702 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
703 paramvec.reserve(5);
704 paramvec.clear();
705 PVPlayerEngineCommandParamUnion param;
706 param.pOsclAny_value = &aIdentifier;
707 paramvec.push_back(param);
708 param.pOsclAny_value = &aParameters;
709 paramvec.push_back(param);
710 param.pOsclAny_value = &aNumParamElements;
711 paramvec.push_back(param);
712 param.pOsclAny_value = &aContext;
713 paramvec.push_back(param);
714 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_GET_PARAMETERS_OOTSYNC, ¶mvec);
715 }
716 }
717
718
DoGetParametersSync(PVPlayerEngineCommand & aCmd)719 PVMFStatus PVPlayerEngine::DoGetParametersSync(PVPlayerEngineCommand& aCmd)
720 {
721 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetParametersSync() In"));
722
723 PVMFStatus status = DoCapConfigGetParametersSync(
724 *((PvmiKeyType*)aCmd.GetParam(0).pOsclAny_value)
725 , *((PvmiKvp**)aCmd.GetParam(1).pOsclAny_value)
726 , *((int*)aCmd.GetParam(2).pOsclAny_value)
727 , *((PvmiCapabilityContext*)aCmd.GetParam(3).pOsclAny_value));
728
729 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetParametersSync() Out"));
730 return status;
731 }
732
733
releaseParameters(PvmiMIOSession aSession,PvmiKvp * aParameters,int aNumElements)734 PVMFStatus PVPlayerEngine::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
735 {
736 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::releaseParameters()"));
737 OSCL_UNUSED_ARG(aSession);
738
739 if (iThreadSafeQueue.IsInThread())
740 {
741 return DoCapConfigReleaseParameters(aParameters, aNumElements);
742 }
743 else
744 {
745 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
746 paramvec.reserve(3);
747 paramvec.clear();
748 PVPlayerEngineCommandParamUnion param;
749 param.pOsclAny_value = aParameters;
750 paramvec.push_back(param);
751 param.int32_value = aNumElements;
752 paramvec.push_back(param);
753 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_RELEASE_PARAMETERS_OOTSYNC, ¶mvec);
754 }
755 }
756
DoReleaseParametersSync(PVPlayerEngineCommand & aCmd)757 PVMFStatus PVPlayerEngine::DoReleaseParametersSync(PVPlayerEngineCommand& aCmd)
758 {
759 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReleaseParametersSync() In"));
760
761 PVMFStatus status = DoCapConfigReleaseParameters(
762 (PvmiKvp*)aCmd.GetParam(0).pOsclAny_value
763 , aCmd.GetParam(1).int32_value);
764
765 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReleaseParametersSync() Out"));
766 return status;
767 }
768
createContext(PvmiMIOSession aSession,PvmiCapabilityContext & aContext)769 void PVPlayerEngine::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
770 {
771 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::createContext()"));
772 OSCL_UNUSED_ARG(aSession);
773 // Context is not really supported so just return some member variable pointer
774 aContext = (PvmiCapabilityContext) & iCapConfigContext;
775 }
776
777
setContextParameters(PvmiMIOSession aSession,PvmiCapabilityContext & aContext,PvmiKvp * aParameters,int aNumParamElements)778 void PVPlayerEngine::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements)
779 {
780 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setContextParameters()"));
781 OSCL_UNUSED_ARG(aSession);
782 OSCL_UNUSED_ARG(aContext);
783 OSCL_UNUSED_ARG(aParameters);
784 OSCL_UNUSED_ARG(aNumParamElements);
785 // This method is not supported so leave
786 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::setContextParameters() is not supported!"));
787 OSCL_LEAVE(OsclErrNotSupported);
788 }
789
790
DeleteContext(PvmiMIOSession aSession,PvmiCapabilityContext & aContext)791 void PVPlayerEngine::DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
792 {
793 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DeleteContext()"));
794 OSCL_UNUSED_ARG(aSession);
795 OSCL_UNUSED_ARG(aContext);
796 // Do nothing since the context is just the a member variable of the engine
797 }
798
799
setParametersSync(PvmiMIOSession aSession,PvmiKvp * aParameters,int aNumElements,PvmiKvp * & aRetKVP)800 void PVPlayerEngine::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
801 {
802 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setParametersSync()"));
803 OSCL_UNUSED_ARG(aSession);
804
805 // Save the parameters in an engine command object
806 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
807 paramvec.reserve(3);
808 paramvec.clear();
809 PVPlayerEngineCommandParamUnion param;
810 param.pOsclAny_value = (OsclAny*)aParameters;
811 paramvec.push_back(param);
812 param.int32_value = (int32) aNumElements;
813 paramvec.push_back(param);
814 param.pOsclAny_value = (OsclAny*) & aRetKVP;
815 paramvec.push_back(param);
816 if (iThreadSafeQueue.IsInThread())
817 {
818 PVPlayerEngineCommand cmd(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS, -1, NULL, ¶mvec);
819
820 // Complete the request synchronously
821 DoCapConfigSetParameters(cmd, true);
822 }
823 else
824 {
825 DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS_OOTSYNC, ¶mvec);
826 }
827 }
828
829
setParametersAsync(PvmiMIOSession aSession,PvmiKvp * aParameters,int aNumElements,PvmiKvp * & aRetKVP,OsclAny * aContext)830 PVMFCommandId PVPlayerEngine::setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext)
831 {
832 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::setParametersAsync()"));
833 OSCL_UNUSED_ARG(aSession);
834
835 // Save the parameters in an engine command object
836 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
837 paramvec.reserve(3);
838 paramvec.clear();
839 PVPlayerEngineCommandParamUnion param;
840 param.pOsclAny_value = (OsclAny*)aParameters;
841 paramvec.push_back(param);
842 param.int32_value = (int32) aNumElements;
843 paramvec.push_back(param);
844 param.pOsclAny_value = (OsclAny*) & aRetKVP;
845 paramvec.push_back(param);
846
847 // Push it to command queue to be processed asynchronously
848 return AddCommandToQueue(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS, (OsclAny*)aContext, ¶mvec, NULL, false);
849 }
850
851
getCapabilityMetric(PvmiMIOSession aSession)852 uint32 PVPlayerEngine::getCapabilityMetric(PvmiMIOSession aSession)
853 {
854 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::getCapabilityMetric()"));
855 OSCL_UNUSED_ARG(aSession);
856 // Not supported so return 0
857 return 0;
858 }
859
860
verifyParametersSync(PvmiMIOSession aSession,PvmiKvp * aParameters,int aNumElements)861 PVMFStatus PVPlayerEngine::verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
862 {
863 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::verifyParametersSync()"));
864 OSCL_UNUSED_ARG(aSession);
865
866 if (iThreadSafeQueue.IsInThread())
867 {
868 return DoCapConfigVerifyParameters(aParameters, aNumElements);
869 }
870 else
871 {
872 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
873 paramvec.reserve(3);
874 paramvec.clear();
875 PVPlayerEngineCommandParamUnion param;
876 param.pOsclAny_value = aParameters;
877 paramvec.push_back(param);
878 param.int32_value = aNumElements;
879 paramvec.push_back(param);
880 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_VERIFY_PARAMETERS_OOTSYNC, ¶mvec);
881 }
882 }
883
DoVerifyParametersSync(PVPlayerEngineCommand & aCmd)884 PVMFStatus PVPlayerEngine::DoVerifyParametersSync(PVPlayerEngineCommand& aCmd)
885 {
886 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyParametersSync() In"));
887
888 PVMFStatus status = DoCapConfigVerifyParameters(
889 (PvmiKvp*)aCmd.GetParam(0).pOsclAny_value
890 , aCmd.GetParam(1).int32_value);
891
892 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyParametersSync() Out"));
893 return status;
894 }
895
AcquireLicense(OsclAny * aLicenseData,uint32 aDataSize,oscl_wchar * aContentName,int32 aTimeoutMsec,const OsclAny * aContextData)896 PVMFCommandId PVPlayerEngine::AcquireLicense(OsclAny* aLicenseData, uint32 aDataSize, oscl_wchar* aContentName, int32 aTimeoutMsec, const OsclAny* aContextData)
897 {
898 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AcquireLicense() wchar"));
899 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
900 paramvec.reserve(3);
901 paramvec.clear();
902 PVPlayerEngineCommandParamUnion param;
903 param.pOsclAny_value = aLicenseData;
904 paramvec.push_back(param);
905 param.uint32_value = aDataSize;
906 paramvec.push_back(param);
907 param.pWChar_value = aContentName;
908 paramvec.push_back(param);
909 param.int32_value = aTimeoutMsec;
910 paramvec.push_back(param);
911 return AddCommandToQueue(PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR, (OsclAny*)aContextData, ¶mvec);
912 }
913
914
AcquireLicense(OsclAny * aLicenseData,uint32 aDataSize,char * aContentName,int32 aTimeoutMsec,const OsclAny * aContextData)915 PVMFCommandId PVPlayerEngine::AcquireLicense(OsclAny* aLicenseData, uint32 aDataSize, char* aContentName, int32 aTimeoutMsec, const OsclAny* aContextData)
916 {
917 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AcquireLicense() char"));
918 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
919 paramvec.reserve(3);
920 paramvec.clear();
921 PVPlayerEngineCommandParamUnion param;
922 param.pOsclAny_value = aLicenseData;
923 paramvec.push_back(param);
924 param.uint32_value = aDataSize;
925 paramvec.push_back(param);
926 param.pChar_value = aContentName;
927 paramvec.push_back(param);
928 param.int32_value = aTimeoutMsec;
929 paramvec.push_back(param);
930 return AddCommandToQueue(PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR, (OsclAny*)aContextData, ¶mvec);
931 }
932
CancelAcquireLicense(PVMFCommandId aCmdId,const OsclAny * aContextData)933 PVMFCommandId PVPlayerEngine::CancelAcquireLicense(PVMFCommandId aCmdId, const OsclAny* aContextData)
934 {
935 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CancelAcquireLicense()"));
936 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
937 paramvec.reserve(1);
938 paramvec.clear();
939 PVPlayerEngineCommandParamUnion param;
940 param.int32_value = aCmdId;
941 paramvec.push_back(param);
942 return AddCommandToQueue(PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE, (OsclAny*)aContextData, ¶mvec);
943 }
944
GetLicenseStatus(PVMFCPMLicenseStatus & aStatus)945 PVMFStatus PVPlayerEngine::GetLicenseStatus(PVMFCPMLicenseStatus& aStatus)
946 {
947 if (iThreadSafeQueue.IsInThread())
948 {
949 if (iSourceNodeCPMLicenseIF)
950 return iSourceNodeCPMLicenseIF->GetLicenseStatus(aStatus);
951 return PVMFFailure;
952 }
953 else
954 {
955 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator> paramvec;
956 paramvec.reserve(2);
957 paramvec.clear();
958 PVPlayerEngineCommandParamUnion param;
959 param.pOsclAny_value = &aStatus;
960 paramvec.push_back(param);
961 return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_LICENSE_STATUS_OOTSYNC, ¶mvec);
962 }
963 }
964
DoGetLicenseStatusSync(PVPlayerEngineCommand & aCmd)965 PVMFStatus PVPlayerEngine::DoGetLicenseStatusSync(PVPlayerEngineCommand& aCmd)
966 {
967 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLicenseStatusSync() In"));
968
969 PVMFStatus status;
970 PVMFCPMLicenseStatus* licstatus = (PVMFCPMLicenseStatus*)(aCmd.GetParam(0).pOsclAny_value);
971 if (!licstatus)
972 {
973 return PVMFFailure;
974 }
975
976 if (iSourceNodeCPMLicenseIF)
977 status = iSourceNodeCPMLicenseIF->GetLicenseStatus(*licstatus);
978 else
979 status = PVMFFailure;
980
981 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLicenseStatusSync() Out"));
982 return status;
983 }
984
addRef()985 void PVPlayerEngine::addRef()
986 {
987 }
988
989
removeRef()990 void PVPlayerEngine::removeRef()
991 {
992 }
993
994
queryInterface(const PVUuid & uuid,PVInterface * & iface)995 bool PVPlayerEngine::queryInterface(const PVUuid& uuid, PVInterface*& iface)
996 {
997 if (uuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
998 {
999 PvmiCapabilityAndConfig* capconfigiface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
1000 iface = OSCL_STATIC_CAST(PVInterface*, capconfigiface);
1001 }
1002 else if (uuid == PVPlayerLicenseAcquisitionInterfaceUuid)
1003 {
1004 PVPlayerLicenseAcquisitionInterface* licacqiface = OSCL_STATIC_CAST(PVPlayerLicenseAcquisitionInterface*, this);
1005 iface = OSCL_STATIC_CAST(PVInterface*, licacqiface);
1006 }
1007 // Check if track level info IF from source node was requested
1008 else if (uuid == PVMF_TRACK_LEVEL_INFO_INTERFACE_UUID && iSourceNodeTrackLevelInfoIF)
1009 {
1010 iface = OSCL_STATIC_CAST(PVInterface*, iSourceNodeTrackLevelInfoIF);
1011 }
1012 //Check if track selection IF from source node was requested
1013 else if (uuid == PVPlayerTrackSelectionInterfaceUuid)
1014 {
1015 PVPlayerTrackSelectionInterface* tseliface = OSCL_STATIC_CAST(PVPlayerTrackSelectionInterface*, this);
1016 iface = OSCL_STATIC_CAST(PVInterface*, tseliface);
1017 }
1018 else
1019 {
1020 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::queryInterface() Unsupported interface UUID."));
1021 return false;
1022 }
1023
1024 return true;
1025 }
1026
1027
1028
PVPlayerEngine()1029 PVPlayerEngine::PVPlayerEngine() :
1030 OsclTimerObject(OsclActiveObject::EPriorityNominal, "PVPlayerEngine"),
1031 iCommandId(0),
1032 iState(PVP_ENGINE_STATE_IDLE),
1033 iCmdStatusObserver(NULL),
1034 iErrorEventObserver(NULL),
1035 iInfoEventObserver(NULL),
1036 iCfgCapCmdObserver(NULL),
1037 iPollingCheckTimer(NULL),
1038 iCommandCompleteStatusInErrorHandling(PVMFSuccess),
1039 iCommandCompleteErrMsgInErrorHandling(NULL),
1040 iCapConfigContext(0),
1041 iNumPendingNodeCmd(0),
1042 iNumPendingSkipCompleteEvent(0),
1043 iNumPendingDatapathCmd(0),
1044 iNumPVMFInfoStartOfDataPending(0),
1045 iDataSource(NULL),
1046 iSourceFormatType(PVMF_MIME_FORMAT_UNKNOWN),
1047 iSourceNode(NULL),
1048 iSourceNodeSessionId(0),
1049 iSourceNodeInitIF(NULL),
1050 iSourceNodeTrackSelIF(NULL),
1051 iSourceNodePBCtrlIF(NULL),
1052 iSourceNodeDirCtrlIF(NULL),
1053 iSourceNodeTrackLevelInfoIF(NULL),
1054 iSourceNodeMetadataExtIF(NULL),
1055 iSourceNodeCapConfigIF(NULL),
1056 iSourceNodeRegInitIF(NULL),
1057 iSourceNodeCPMLicenseIF(NULL),
1058 iSourceNodePVInterfaceInit(NULL),
1059 iSourceNodePVInterfaceTrackSel(NULL),
1060 iSourceNodePVInterfacePBCtrl(NULL),
1061 iSourceNodePVInterfaceDirCtrl(NULL),
1062 iSourceNodePVInterfaceTrackLevelInfo(NULL),
1063 iSourceNodePVInterfaceMetadataExt(NULL),
1064 iSourceNodePVInterfaceCapConfig(NULL),
1065 iSourceNodePVInterfaceRegInit(NULL),
1066 iSourceNodePVInterfaceCPMLicense(NULL),
1067 iCPMGetLicenseCmdId(0),
1068 iMetadataValuesCopiedInCallBack(true),
1069 iReleaseMetadataValuesPending(false),
1070 iCurrentContextListMemPool(12),
1071 iNumberCancelCmdPending(0),
1072 iLogger(NULL),
1073 iReposLogger(NULL),
1074 iPerfLogger(NULL),
1075 iClockNotificationsInf(NULL),
1076 iPlayStatusCallbackTimerID(0),
1077 iPlayStatusCallbackTimerMarginWindow(0),
1078 iCurrCallbackTimerLatency(0),
1079 iPlaybackClockRate(100000),
1080 iOutsideTimebase(NULL),
1081 iPlaybackClockRate_New(100000),
1082 iOutsideTimebase_New(NULL),
1083 iPlaybackDirection(1),
1084 iPlaybackDirection_New(1),
1085 iChangePlaybackDirectionWhenResuming(false),
1086 iEndTimeCheckEnabled(false),
1087 iQueuedRangePresent(false),
1088 iChangePlaybackPositionWhenResuming(false),
1089 iActualNPT(0),
1090 iTargetNPT(0),
1091 iActualMediaDataTS(0),
1092 iSkipMediaDataTS(0),
1093 iStartNPT(0),
1094 iStartMediaDataTS(0),
1095 iWatchDogTimerInterval(0),
1096 iSeekPointBeforeTargetNPT(0),
1097 iSeekPointAfterTargetNPT(0),
1098 iForwardReposFlag(false),
1099 iBackwardReposFlag(false),
1100 iPlayStatusTimerEnabled(false),
1101 iDataReadySent(false),
1102 iPlaybackPausedDueToEndOfClip(false),
1103 iSourceDurationAvailable(false),
1104 iSourceDurationInMS(0),
1105 iPBPosEnable(true),
1106 iPBPosStatusUnit(PVPLAYERENGINE_CONFIG_PBPOSSTATUSUNIT_DEF),
1107 iPBPosStatusInterval(PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_DEF),
1108 iEndTimeCheckInterval(PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_DEF),
1109 iSeekToSyncPoint(PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINT_DEF),
1110 iSkipToRequestedPosition(PVPLAYERENGINE_CONFIG_SKIPTOREQUESTEDPOS_DEF),
1111 iBackwardRepos(false),
1112 iSyncPointSeekWindow(PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_DEF),
1113 iNodeCmdTimeout(PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_DEF),
1114 iNodeDataQueuingTimeout(PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_DEF),
1115 iProdInfoProdName(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PRODNAME_STRING)),
1116 iProdInfoPartNum(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PARTNUM_STRING)),
1117 iProdInfoHWPlatform(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_HWPLATFORM_STRING)),
1118 iProdInfoSWPlatform(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_SWPLATFORM_STRING)),
1119 iProdInfoDevice(_STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_DEVICE_STRING)),
1120 iStreamID(0),
1121 iAlternateSrcFormatIndex(0),
1122 iRollOverState(RollOverStateIdle),
1123 iTrackSelectionHelper(NULL),
1124 iPlaybackPositionMode(PVPPBPOS_MODE_UNKNOWN),
1125 iOverflowFlag(false)
1126 {
1127 iCurrentBeginPosition.iIndeterminate = true;
1128 iCurrentEndPosition.iIndeterminate = true;
1129 iCurrentBeginPosition.iPlayListUri = NULL;
1130 iQueuedBeginPosition.iIndeterminate = true;
1131 iQueuedEndPosition.iIndeterminate = true;
1132 iChangeDirectionNPT.iIndeterminate = true;
1133
1134 iSyncMarginVideo.min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
1135 iSyncMarginVideo.max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
1136 iSyncMarginAudio.min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
1137 iSyncMarginAudio.max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
1138 iSyncMarginText.min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
1139 iSyncMarginText.max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
1140
1141 iNodeUuids.clear();
1142 }
1143
1144
Construct(PVCommandStatusObserver * aCmdStatusObserver,PVErrorEventObserver * aErrorEventObserver,PVInformationalEventObserver * aInfoEventObserver)1145 void PVPlayerEngine::Construct(PVCommandStatusObserver* aCmdStatusObserver,
1146 PVErrorEventObserver *aErrorEventObserver,
1147 PVInformationalEventObserver *aInfoEventObserver)
1148 {
1149 iCommandIdMut.Create();
1150 iOOTSyncCommandSem.Create();
1151 iThreadSafeQueue.Configure(this);
1152
1153 iCmdStatusObserver = aCmdStatusObserver;
1154 iInfoEventObserver = aInfoEventObserver;
1155 iErrorEventObserver = aErrorEventObserver;
1156
1157 // Allocate memory for vectors
1158 // If a leave occurs, let it bubble up
1159 iCurrentCmd.reserve(1);
1160 iCmdToCancel.reserve(1);
1161 iCmdToDlaCancel.reserve(1);
1162 iPendingCmds.reserve(PVPLAYERENGINE_NUM_COMMANDS);
1163 iPvmiKvpCapNConfig.reserve(20);
1164
1165 iDatapathList.reserve(3);
1166
1167 iCurrentContextList.reserve(12);
1168
1169 iMetadataIFList.reserve(6);
1170 iMetadataIFList.clear();
1171
1172 iMetadataKeyReleaseList.reserve(6);
1173 iMetadataKeyReleaseList.clear();
1174
1175 iMetadataValueReleaseList.reserve(6);
1176 iMetadataValueReleaseList.clear();
1177
1178 AddToScheduler();
1179
1180 // Retrieve the logger object
1181 iLogger = PVLogger::GetLoggerObject("PVPlayerEngine");
1182 iPerfLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.perf.engine");
1183 iReposLogger = PVLogger::GetLoggerObject("pvplayerrepos.engine");
1184
1185 // Initialize the playback clock to use tickcount timebase
1186 iPlaybackClock.SetClockTimebase(iPlaybackTimebase);
1187 uint32 starttime = 0;
1188 bool overflow = 0;
1189 iPlaybackClock.SetStartTime32(starttime, PVMF_MEDIA_CLOCK_MSEC, overflow);
1190 iPlaybackClock.ConstructMediaClockNotificationsInterface(iClockNotificationsInf, *this,
1191 iCurrCallbackTimerLatency);
1192
1193 // Initialize the OSCL timer for polling checks
1194 iPollingCheckTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, ("playerengine_pollingcheck"));
1195 iPollingCheckTimer->SetObserver(this);
1196 iPollingCheckTimer->SetFrequency(10); // 100 ms resolution
1197
1198 iWatchDogTimer = OSCL_NEW(PVPlayerWatchdogTimer, (this));
1199
1200 PVPlayerRegistryPopulator::Populate(iPlayerNodeRegistry, iPlayerRecognizerRegistry);
1201
1202 return;
1203 }
1204
1205
Run()1206 void PVPlayerEngine::Run()
1207 {
1208 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() In"));
1209 int32 leavecode = 0;
1210
1211 /* Engine AO will execute commands in the following sequence
1212 * 1) If Engine state is Resetting, which will happen when Engine does ErrorHandling,
1213 * processing Reset or CancelAllCommands
1214 * issued by the app, engine will not try to execute any other command during this state.
1215 * 2) If Engine is not in Resetting state then it will process commands in the following order, which ever is true:
1216 * (i) If Engine needs to do Error handling because of some error from Source Node or Datapath.
1217 * Either start error handling or complete it.
1218 * (ii) If Engine has Reset or CancelAllCommands in CurrentCommandQueue,
1219 * engine will do CommandComplete for the CurrentCommand.
1220 * (iii) If Engine has Prepare in CurrentCommandQueue, engine will call DoPrepare again
1221 * as a part of track selection logic
1222 * (iv) If Engine has CancelAllCommands or CancelAcquireLicense in Pending CommandQueue,
1223 * engine will start Cancel commands.
1224 * (v) Go for Rollover if in Init State and Roll-over is ongoing.
1225 * (vi) Process which ever command is pushed in Pending queue.
1226 * Engine will process any one of the command as listed above in the same order.
1227 * Every time engine AO is scheduled, engine will go through
1228 * these steps.
1229 */
1230
1231 if (iState == PVP_ENGINE_STATE_RESETTING)
1232 {
1233 //this means error handling, reset or cancelall is still in progress
1234 //pls note that the state will be set to idle
1235 //in either HandleSourceNodeReset or HandleDataPathReset
1236 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1237 (0, "PVPlayerEngine::Run() Return engine in resetting state, No processing until engine is in Idle state"));
1238 return;
1239 }
1240
1241 /* Check if ErrorHandling request was made */
1242 if (!iPendingCmds.empty())
1243 {
1244 switch (iPendingCmds.top().GetCmdType())
1245 {
1246 case PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE:
1247 case PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT:
1248 case PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE:
1249 case PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE:
1250 case PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME:
1251 case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE:
1252 case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE:
1253 case PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP:
1254 case PVP_ENGINE_COMMAND_ERROR_HANDLING_CANCEL_ALL_COMMANDS:
1255 case PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL:
1256 {
1257 // go in error handling right away
1258 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing Error Handling request"));
1259 PVMFStatus retVal = DoErrorHandling();
1260 if (retVal == PVMFSuccess)
1261 {
1262 iPendingCmds.pop();
1263 RunIfNotReady(); // schedule the engine AO to process other commands in queue if any.
1264 }
1265 return;
1266 }
1267
1268 default:
1269 break;
1270 }
1271 }
1272
1273 // if current command being processed is reset or cancelAll and
1274 // Player engine state is idle then remove the data source
1275 // and do reset/cancelAll command complete
1276 // OR
1277 // if current command being processed is prepare, need to call
1278 // DoPrepare again because of track selection
1279 if (!iCurrentCmd.empty())
1280 {
1281 if ((iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_RESET) ||
1282 (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_COMMAND) ||
1283 (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS))
1284 {
1285 if (iState != PVP_ENGINE_STATE_IDLE)
1286 {
1287 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Engine not in Idle State, asserting"));
1288 OSCL_ASSERT(false);
1289 }
1290 // First destroy all datapaths.
1291 DoRemoveAllSinks();
1292 // now remove the source node.
1293 if (iDataSource)
1294 {
1295 RemoveDataSourceSync(*iDataSource);
1296 }
1297
1298 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFSuccess);
1299 }
1300 else if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_PREPARE)
1301 {
1302 PVMFStatus cmdstatus = DoPrepare(iCurrentCmd[0]);
1303
1304 if (cmdstatus != PVMFSuccess && cmdstatus != PVMFPending)
1305 {
1306 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Command failed CmdId %d Status %d",
1307 iCurrentCmd[0].GetCmdId(), cmdstatus));
1308 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), cmdstatus);
1309 }
1310 }
1311 }
1312
1313 /* Check if Cancel()/CancelAll()/CancelAcquireLicense request was made */
1314 if (!iPendingCmds.empty())
1315 {
1316 if (iPendingCmds.top().GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_COMMAND)
1317 {
1318 // Process it right away
1319 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing Cancel() request"));
1320 PVPlayerEngineCommand cmd(iPendingCmds.top());
1321 iPendingCmds.pop();
1322 if ((!iCurrentCmd.empty()) && (iCurrentCmd[0].GetCmdId() == cmd.GetParam(0).int32_value))
1323 {
1324 // We need to cancel the ongoing command. In this case issue cancelAll
1325 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1326 (0, "PVPlayerEngine::Run: Command to Cancel is ongoing so issue CancelAll"));
1327 DoCancelAllCommands(cmd);
1328 }
1329 else
1330 {
1331 // The command to be cancelled is in the pending queue
1332 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1333 (0, "PVPlayerEngine::Run: Command to Cancel is pending so just Cancel"));
1334 DoCancelCommand(cmd);
1335 }
1336 return;
1337 }
1338 else if (iPendingCmds.top().GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS)
1339 {
1340 // Process it right away
1341 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing CancelAll() request"));
1342 PVPlayerEngineCommand cmd(iPendingCmds.top());
1343 iPendingCmds.pop();
1344 DoCancelAllCommands(cmd);
1345 return;
1346 }
1347 else if (iPendingCmds.top().GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE)
1348 {
1349 // Process it right away
1350 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing CancelAcquireLicesense() request"));
1351 PVPlayerEngineCommand cmd(iPendingCmds.top());
1352 iPendingCmds.pop();
1353 DoCancelAcquireLicense(cmd);
1354 return;
1355 }
1356 }
1357
1358 if (iRollOverState == RollOverStateStart)
1359 {
1360 if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_INIT)
1361 {
1362 //implies that we are doing a source rollover
1363 PVMFStatus status =
1364 DoSourceNodeRollOver(iCurrentCmd[0].iCmdId,
1365 iCurrentCmd[0].iContextData);
1366
1367 if (status != PVMFPending)
1368 {
1369 if (CheckForSourceRollOver())
1370 {
1371 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() DoSourceNodeRollOver Failed, alternate source node for rollover is available"));
1372 RunIfNotReady();
1373 return;
1374 }
1375 // roll over failed
1376 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() DoSourceNodeRollOver Failed, go in error handling"));
1377 bool ehPending = CheckForPendingErrorHandlingCmd();
1378 if (ehPending)
1379 {
1380 // there should be no error handling queued.
1381 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Already EH pending, should never happen"));
1382 return;
1383 }
1384 // go in error handling
1385 iCommandCompleteStatusInErrorHandling = status;
1386 iCommandCompleteErrMsgInErrorHandling = NULL;
1387 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
1388 iRollOverState = RollOverStateIdle;
1389 return;
1390 }
1391 else
1392 {
1393 iRollOverState = RollOverStateInProgress;
1394 }
1395 }
1396 else
1397 {
1398 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Source Roll Over In Progress But Incorrect Engine Cmd"));
1399 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFErrInvalidState);
1400 }
1401 return;
1402 }
1403
1404 if (iRollOverState == RollOverStateInProgress)
1405 {
1406 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RunL() Source Roll Over In Progress "));
1407 return;
1408 }
1409
1410 // Handle other requests normally
1411 if (!iPendingCmds.empty() && iCurrentCmd.empty())
1412 {
1413 // Retrieve the first pending command from queue
1414 PVPlayerEngineCommand cmd(iPendingCmds.top());
1415 iPendingCmds.pop();
1416
1417 // Put in on the current command queue
1418 leavecode = 0;
1419 OSCL_TRY(leavecode, iCurrentCmd.push_front(cmd));
1420 OSCL_FIRST_CATCH_ANY(leavecode,
1421 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Command could not be pushed onto iCurrentCmd vector"));
1422 EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), PVMFErrNoMemory);
1423 return;);
1424
1425 // Process the command according to the cmd type
1426 PVMFStatus cmdstatus = PVMFSuccess;
1427 bool ootsync = false;
1428 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Processing command with type=%d", cmd.GetCmdType()));
1429 switch (cmd.GetCmdType())
1430 {
1431 case PVP_ENGINE_COMMAND_GET_SDK_INFO:
1432 cmdstatus = DoGetSDKInfo(cmd);
1433 break;
1434
1435 case PVP_ENGINE_COMMAND_GET_SDK_MODULE_INFO:
1436 // GetSDKModuleInfo is currently not supported
1437 cmdstatus = PVMFErrNotSupported;
1438 break;
1439
1440 case PVP_ENGINE_COMMAND_SET_LOG_APPENDER:
1441 cmdstatus = DoSetLogAppender(cmd);
1442 break;
1443
1444 case PVP_ENGINE_COMMAND_REMOVE_LOG_APPENDER:
1445 cmdstatus = DoRemoveLogAppender(cmd);
1446 break;
1447
1448 case PVP_ENGINE_COMMAND_SET_LOG_LEVEL:
1449 cmdstatus = DoSetLogLevel(cmd);
1450 break;
1451
1452 case PVP_ENGINE_COMMAND_GET_LOG_LEVEL:
1453 cmdstatus = DoGetLogLevel(cmd);
1454 break;
1455
1456 case PVP_ENGINE_COMMAND_QUERY_UUID:
1457 cmdstatus = DoQueryUUID(cmd);;
1458 break;
1459
1460 case PVP_ENGINE_COMMAND_QUERY_INTERFACE:
1461 cmdstatus = DoQueryInterface(cmd);
1462 break;
1463
1464 case PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE:
1465 cmdstatus = DoGetPVPlayerState(cmd, false);
1466 break;
1467
1468 case PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE_OOTSYNC:
1469 ootsync = true;
1470 cmdstatus = DoGetPVPlayerState(cmd, true);
1471 break;
1472
1473 case PVP_ENGINE_COMMAND_ADD_DATA_SOURCE:
1474 cmdstatus = DoAddDataSource(cmd);
1475 break;
1476
1477 case PVP_ENGINE_COMMAND_INIT:
1478 cmdstatus = DoInit(cmd);
1479 break;
1480
1481 case PVP_ENGINE_COMMAND_GET_METADATA_KEY:
1482 cmdstatus = DoGetMetadataKey(cmd);
1483 break;
1484
1485 case PVP_ENGINE_COMMAND_GET_METADATA_VALUE:
1486 cmdstatus = DoGetMetadataValue(cmd);
1487 break;
1488
1489 case PVP_ENGINE_COMMAND_RELEASE_METADATA_VALUE:
1490 cmdstatus = DoReleaseMetadataValues(cmd);
1491 break;
1492
1493 case PVP_ENGINE_COMMAND_ADD_DATA_SINK:
1494 cmdstatus = DoAddDataSink(cmd);
1495 break;
1496
1497 case PVP_ENGINE_COMMAND_GET_CURRENT_POSITION:
1498 cmdstatus = DoGetCurrentPosition(cmd, false);
1499 break;
1500
1501 case PVP_ENGINE_COMMAND_GET_CURRENT_POSITION_OOTSYNC:
1502 ootsync = true;
1503 cmdstatus = DoGetCurrentPosition(cmd, true);
1504 break;
1505
1506 case PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE:
1507 cmdstatus = DoSetPlaybackRange(cmd);
1508 break;
1509
1510 case PVP_ENGINE_COMMAND_GET_PLAYBACK_RANGE:
1511 cmdstatus = DoGetPlaybackRange(cmd);
1512 break;
1513
1514 case PVP_ENGINE_COMMAND_SET_PLAYBACK_RATE:
1515 cmdstatus = DoSetPlaybackRate(cmd);
1516 break;
1517
1518 case PVP_ENGINE_COMMAND_GET_PLAYBACK_RATE:
1519 cmdstatus = DoGetPlaybackRate(cmd);
1520 break;
1521
1522 case PVP_ENGINE_COMMAND_GET_PLAYBACK_MINMAX_RATE:
1523 cmdstatus = DoGetPlaybackMinMaxRate(cmd);
1524 break;
1525
1526 case PVP_ENGINE_COMMAND_PREPARE:
1527 cmdstatus = DoPrepare(cmd);
1528 break;
1529
1530 case PVP_ENGINE_COMMAND_START:
1531 cmdstatus = DoStart(cmd);
1532 break;
1533
1534 case PVP_ENGINE_COMMAND_PAUSE:
1535 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP:
1536 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED:
1537 cmdstatus = DoPause(cmd);
1538 break;
1539
1540 case PVP_ENGINE_COMMAND_RESUME:
1541 cmdstatus = DoResume(cmd);
1542 break;
1543
1544 case PVP_ENGINE_COMMAND_STOP:
1545 cmdstatus = DoStop(cmd);
1546 break;
1547
1548 case PVP_ENGINE_COMMAND_REMOVE_DATA_SINK:
1549 cmdstatus = DoRemoveDataSink(cmd);
1550 break;
1551
1552 case PVP_ENGINE_COMMAND_RESET:
1553 cmdstatus = DoReset(cmd);
1554 break;
1555
1556 case PVP_ENGINE_COMMAND_REMOVE_DATA_SOURCE:
1557 cmdstatus = DoRemoveDataSource(cmd);
1558 break;
1559
1560 case PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS:
1561 cmdstatus = DoCapConfigSetParameters(cmd, false);
1562 break;
1563
1564 case PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS_OOTSYNC:
1565 ootsync = true;
1566 cmdstatus = DoCapConfigSetParameters(cmd, true);
1567 break;
1568
1569 case PVP_ENGINE_COMMAND_CAPCONFIG_GET_PARAMETERS_OOTSYNC:
1570 ootsync = true;
1571 cmdstatus = DoGetParametersSync(cmd);
1572 break;
1573
1574 case PVP_ENGINE_COMMAND_CAPCONFIG_RELEASE_PARAMETERS_OOTSYNC:
1575 ootsync = true;
1576 cmdstatus = DoReleaseParametersSync(cmd);
1577 break;
1578
1579 case PVP_ENGINE_COMMAND_CAPCONFIG_VERIFY_PARAMETERS_OOTSYNC:
1580 ootsync = true;
1581 cmdstatus = DoVerifyParametersSync(cmd);
1582 break;
1583
1584 case PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR:
1585 case PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR:
1586 cmdstatus = DoAcquireLicense(cmd);
1587 break;
1588
1589 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW:
1590 cmdstatus = DoSourceUnderflowAutoPause(cmd);
1591 break;
1592
1593 case PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY:
1594 cmdstatus = DoSourceDataReadyAutoResume(cmd);
1595 break;
1596
1597 case PVP_ENGINE_COMMAND_CAPCONFIG_SET_OBSERVER_OOTSYNC:
1598 ootsync = true;
1599 cmdstatus = DoSetObserverSync(cmd);
1600 break;
1601
1602 case PVP_ENGINE_COMMAND_GET_LICENSE_STATUS_OOTSYNC:
1603 ootsync = true;
1604 cmdstatus = DoGetLicenseStatusSync(cmd);
1605 break;
1606
1607 case PVP_ENGINE_COMMAND_CANCEL_COMMAND:
1608 // Cancel() should not be handled here
1609 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() CancelCommand should be not handled in here. Return Failure"));
1610 cmdstatus = PVMFFailure;
1611 break;
1612
1613 case PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS:
1614 // CancelAll() should not be handled here
1615 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() CancelAllCommands should be not handled in here. Return Failure"));
1616 cmdstatus = PVMFFailure;
1617 break;
1618
1619 default:
1620 // Just handle as "not supported"
1621 cmdstatus = PVMFErrNotSupported;
1622 break;
1623 }
1624
1625 if (ootsync)
1626 {
1627 OOTSyncCommandComplete(cmd, cmdstatus);
1628 // Empty out the current cmd vector and set active if there are other pending commands
1629 iCurrentCmd.erase(iCurrentCmd.begin());
1630 if (!iPendingCmds.empty())
1631 {
1632 RunIfNotReady();
1633 }
1634 }
1635 else if (cmdstatus != PVMFSuccess && cmdstatus != PVMFPending)
1636 {
1637 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::Run() Command failed CmdId %d Status %d",
1638 cmd.GetCmdId(), cmdstatus));
1639 EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), cmdstatus);
1640 }
1641 }
1642
1643 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::Run() Out"));
1644 }
1645
FindNodeTypeByNode(PVMFNodeInterface * aUnknownNode,PVPlayerNodeType & aNodeType,int32 & aDatapathListIndex)1646 bool PVPlayerEngine::FindNodeTypeByNode(PVMFNodeInterface* aUnknownNode, PVPlayerNodeType& aNodeType, int32& aDatapathListIndex)
1647 {
1648 if (aUnknownNode == NULL)
1649 {
1650 // Cannot check with node pointer being NULL
1651 // Might bring up false positives
1652 aNodeType = PVP_NODETYPE_UNKNOWN;
1653 aDatapathListIndex = -1;
1654 return false;
1655 }
1656
1657 // Go through each engine datapath and find whether
1658 // the specified node is a dec node or sink node
1659 for (uint32 i = 0; i < iDatapathList.size(); ++i)
1660 {
1661 if (iDatapathList[i].iDecNode == aUnknownNode)
1662 {
1663 aNodeType = PVP_NODETYPE_DECODER;
1664 aDatapathListIndex = i;
1665 return true;
1666 }
1667 else if (iDatapathList[i].iSinkNode == aUnknownNode)
1668 {
1669 aNodeType = PVP_NODETYPE_SINK;
1670 aDatapathListIndex = i;
1671 return true;
1672 }
1673 }
1674
1675 // Could not determine the types
1676 aNodeType = PVP_NODETYPE_UNKNOWN;
1677 aDatapathListIndex = -1;
1678 return false;
1679 }
1680
FindTrackForDatapathUsingMimeString(bool & aVideoTrack,bool & aAudioTrack,bool & aTextTrack,PVPlayerEngineDatapath * aDatapath)1681 bool PVPlayerEngine::FindTrackForDatapathUsingMimeString(bool& aVideoTrack, bool& aAudioTrack, bool& aTextTrack, PVPlayerEngineDatapath* aDatapath)
1682 {
1683 if (aDatapath->iTrackInfo)
1684 {
1685 char* mimeString = aDatapath->iTrackInfo->getTrackMimeType().get_str();
1686
1687 if ((pv_mime_strcmp(mimeString, PVMF_MIME_YUV420) == 0) ||
1688 (pv_mime_strcmp(mimeString, PVMF_MIME_YUV422) == 0) ||
1689 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB8) == 0) ||
1690 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB12) == 0) ||
1691 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB16) == 0) ||
1692 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB24) == 0) ||
1693 (pv_mime_strcmp(mimeString, PVMF_MIME_M4V) == 0) ||
1694 (pv_mime_strcmp(mimeString, PVMF_MIME_H2631998) == 0) ||
1695 (pv_mime_strcmp(mimeString, PVMF_MIME_H2632000) == 0) ||
1696 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_RAW) == 0) ||
1697 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_MP4) == 0) ||
1698 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO) == 0) ||
1699 (pv_mime_strcmp(mimeString, PVMF_MIME_WMV) == 0) ||
1700 (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_VIDEO) == 0))
1701 {
1702 aVideoTrack = true;
1703 aAudioTrack = false;
1704 aTextTrack = false;
1705 return true;
1706 }
1707 else if (pv_mime_strcmp(mimeString, PVMF_MIME_3GPP_TIMEDTEXT) == 0)
1708 {
1709 aVideoTrack = false;
1710 aAudioTrack = false;
1711 aTextTrack = true;
1712 return true;
1713 }
1714 else if ((pv_mime_strcmp(mimeString, PVMF_MIME_PCM) == 0) ||
1715 (pv_mime_strcmp(mimeString, PVMF_MIME_PCM8) == 0) ||
1716 (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16) == 0) ||
1717 (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16_BE) == 0) ||
1718 (pv_mime_strcmp(mimeString, PVMF_MIME_ULAW) == 0) ||
1719 (pv_mime_strcmp(mimeString, PVMF_MIME_ALAW) == 0) ||
1720 (pv_mime_strcmp(mimeString, PVMF_MIME_AMR) == 0) ||
1721 (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB) == 0) ||
1722 (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IETF) == 0) ||
1723 (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB_IETF) == 0) ||
1724 (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IF2) == 0) ||
1725 (pv_mime_strcmp(mimeString, PVMF_MIME_EVRC) == 0) ||
1726 (pv_mime_strcmp(mimeString, PVMF_MIME_MP3) == 0) ||
1727 (pv_mime_strcmp(mimeString, PVMF_MIME_ADIF) == 0) ||
1728 (pv_mime_strcmp(mimeString, PVMF_MIME_ADTS) == 0) ||
1729 (pv_mime_strcmp(mimeString, PVMF_MIME_LATM) == 0) ||
1730 (pv_mime_strcmp(mimeString, PVMF_MIME_MPEG4_AUDIO) == 0) ||
1731 (pv_mime_strcmp(mimeString, PVMF_MIME_G723) == 0) ||
1732 (pv_mime_strcmp(mimeString, PVMF_MIME_G726) == 0) ||
1733 (pv_mime_strcmp(mimeString, PVMF_MIME_WMA) == 0) ||
1734 (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_AMR) == 0) ||
1735 (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_AUDIO) == 0) ||
1736 (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_MPEG4_AUDIO) == 0) ||
1737 (pv_mime_strcmp(mimeString, PVMF_MIME_3640) == 0))
1738 {
1739 aVideoTrack = false;
1740 aAudioTrack = true;
1741 aTextTrack = false;
1742 return true;
1743 }
1744 else
1745 {
1746 aVideoTrack = false;
1747 aAudioTrack = false;
1748 aTextTrack = false;
1749 return false;
1750 }
1751 }
1752
1753 aVideoTrack = false;
1754 aAudioTrack = false;
1755 aTextTrack = false;
1756 return false;
1757 }
1758
FindDatapathForTrackUsingMimeString(bool aVideoTrack,bool aAudioTrack,bool aTextTrack,int32 & aDatapathListIndex)1759 bool PVPlayerEngine::FindDatapathForTrackUsingMimeString(bool aVideoTrack, bool aAudioTrack, bool aTextTrack, int32& aDatapathListIndex)
1760 {
1761 for (uint32 i = 0; i < iDatapathList.size(); i++)
1762 {
1763 if (iDatapathList[i].iTrackInfo)
1764 {
1765 char* mimeString = iDatapathList[i].iTrackInfo->getTrackMimeType().get_str();
1766 if (aVideoTrack)
1767 {
1768 // find a datapath using the mime string for Video track
1769 if ((pv_mime_strcmp(mimeString, PVMF_MIME_YUV420) == 0) ||
1770 (pv_mime_strcmp(mimeString, PVMF_MIME_YUV422) == 0) ||
1771 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB8) == 0) ||
1772 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB12) == 0) ||
1773 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB16) == 0) ||
1774 (pv_mime_strcmp(mimeString, PVMF_MIME_RGB24) == 0) ||
1775 (pv_mime_strcmp(mimeString, PVMF_MIME_M4V) == 0) ||
1776 (pv_mime_strcmp(mimeString, PVMF_MIME_H2631998) == 0) ||
1777 (pv_mime_strcmp(mimeString, PVMF_MIME_H2632000) == 0) ||
1778 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_RAW) == 0) ||
1779 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO_MP4) == 0) ||
1780 (pv_mime_strcmp(mimeString, PVMF_MIME_H264_VIDEO) == 0) ||
1781 (pv_mime_strcmp(mimeString, PVMF_MIME_WMV) == 0) ||
1782 (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_VIDEO) == 0))
1783 {
1784 aDatapathListIndex = i;
1785 return true;
1786 }
1787 }
1788 else if (aAudioTrack)
1789 {
1790 // find a datapath using the mime string for Audio track
1791 if ((pv_mime_strcmp(mimeString, PVMF_MIME_PCM) == 0) ||
1792 (pv_mime_strcmp(mimeString, PVMF_MIME_PCM8) == 0) ||
1793 (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16) == 0) ||
1794 (pv_mime_strcmp(mimeString, PVMF_MIME_PCM16_BE) == 0) ||
1795 (pv_mime_strcmp(mimeString, PVMF_MIME_ULAW) == 0) ||
1796 (pv_mime_strcmp(mimeString, PVMF_MIME_ALAW) == 0) ||
1797 (pv_mime_strcmp(mimeString, PVMF_MIME_AMR) == 0) ||
1798 (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB) == 0) ||
1799 (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IETF) == 0) ||
1800 (pv_mime_strcmp(mimeString, PVMF_MIME_AMRWB_IETF) == 0) ||
1801 (pv_mime_strcmp(mimeString, PVMF_MIME_AMR_IF2) == 0) ||
1802 (pv_mime_strcmp(mimeString, PVMF_MIME_EVRC) == 0) ||
1803 (pv_mime_strcmp(mimeString, PVMF_MIME_MP3) == 0) ||
1804 (pv_mime_strcmp(mimeString, PVMF_MIME_ADIF) == 0) ||
1805 (pv_mime_strcmp(mimeString, PVMF_MIME_ADTS) == 0) ||
1806 (pv_mime_strcmp(mimeString, PVMF_MIME_LATM) == 0) ||
1807 (pv_mime_strcmp(mimeString, PVMF_MIME_MPEG4_AUDIO) == 0) ||
1808 (pv_mime_strcmp(mimeString, PVMF_MIME_G723) == 0) ||
1809 (pv_mime_strcmp(mimeString, PVMF_MIME_G726) == 0) ||
1810 (pv_mime_strcmp(mimeString, PVMF_MIME_WMA) == 0) ||
1811 (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_AMR) == 0) ||
1812 (pv_mime_strcmp(mimeString, PVMF_MIME_REAL_AUDIO) == 0) ||
1813 (pv_mime_strcmp(mimeString, PVMF_MIME_ASF_MPEG4_AUDIO) == 0) ||
1814 (pv_mime_strcmp(mimeString, PVMF_MIME_3640) == 0))
1815 {
1816 aDatapathListIndex = i;
1817 return true;
1818 }
1819 }
1820 else if (aTextTrack)
1821 {
1822 // find a datapath using the mime string for Text track
1823 if (pv_mime_strcmp(mimeString, PVMF_MIME_3GPP_TIMEDTEXT) == 0)
1824 {
1825 aDatapathListIndex = i;
1826 return true;
1827 }
1828 }
1829 else
1830 {
1831 // Unknown track
1832 aDatapathListIndex = -1;
1833 return false;
1834 }
1835 }
1836 }
1837
1838 // Unknown track
1839 aDatapathListIndex = -1;
1840 return false;
1841 }
1842
1843
NodeCommandCompleted(const PVMFCmdResp & aResponse)1844 void PVPlayerEngine::NodeCommandCompleted(const PVMFCmdResp& aResponse)
1845 {
1846 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() In"));
1847
1848 int32 leavecode = 0;
1849
1850 // Check if a cancel command completed
1851 uint32* context_uint32 = (uint32*)(aResponse.GetContext());
1852 if (context_uint32 == &iNumberCancelCmdPending)
1853 {
1854 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Cancel in node completed for cancel command. Pending %d", iNumberCancelCmdPending));
1855 --iNumberCancelCmdPending;
1856
1857 // If cmd to cancel was GetMetadataKeys() or GetMetadataValues() and if these commands return with
1858 // success then first release the memory for the node which return with success.
1859 if (iCmdToCancel[0].GetCmdType() == PVP_ENGINE_COMMAND_GET_METADATA_KEY &&
1860 aResponse.GetCmdStatus() == PVMFSuccess)
1861 {
1862 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1863 (0, "PVPlayerEngine::NodeCommandCompleted() Cancel in node completed for GetMetadataKeys with success, release memory."));
1864 // Release the memory allocated for the metadata keys
1865 uint32 numkeysadded = iGetMetadataKeysParam.iKeyList->size() - iGetMetadataKeysParam.iNumKeyEntriesInList;
1866 uint32 start = iGetMetadataKeysParam.iNumKeyEntriesInList;
1867 uint32 end = iGetMetadataKeysParam.iNumKeyEntriesInList + numkeysadded - 1;
1868
1869 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iInterface;
1870 OSCL_ASSERT(mdif != NULL);
1871 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), start, end);
1872 }
1873 else if (iCmdToCancel[0].GetCmdType() == PVP_ENGINE_COMMAND_GET_METADATA_VALUE &&
1874 aResponse.GetCmdStatus() == PVMFSuccess)
1875 {
1876 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1877 (0, "PVPlayerEngine::NodeCommandCompleted() Cancel in node completed for GetMetadataValue with success, release memory."));
1878 // Release the memory allocated for the metadata values
1879 uint32 numkeysadded = iGetMetadataValuesParam.iKeyList->size() - iGetMetadataValuesParam.iNumValueEntriesInList;
1880 uint32 start = iGetMetadataValuesParam.iNumValueEntriesInList;
1881 uint32 end = iGetMetadataValuesParam.iNumValueEntriesInList + numkeysadded - 1;
1882
1883 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iInterface;
1884 OSCL_ASSERT(mdif != NULL);
1885 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), start, end);
1886
1887 iReleaseMetadataValuesPending = false;
1888 }
1889
1890 if (iNumberCancelCmdPending == 0)
1891 {
1892 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Cancelling of all node/datapath commands complete, now reset all nodes"));
1893 // Clear the CancelCmd queue as the cmd has been cancelled.
1894 iCmdToCancel.clear();
1895
1896 RemoveDatapathContextFromList(); // empty left over contexts from cancelled datapath commands
1897 // Now reset the source node
1898 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
1899
1900 PVMFCommandId cmdid = -1;
1901 int32 leavecode = 0;
1902 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
1903 OSCL_FIRST_CATCH_ANY(leavecode,
1904
1905 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Reset on iSourceNode did a leave!"));
1906 FreeEngineContext(context);
1907 OSCL_ASSERT(false);
1908 return);
1909
1910 SetEngineState(PVP_ENGINE_STATE_RESETTING);
1911 }
1912 return;
1913 }
1914
1915 PVPlayerEngineContext* nodecontext = (PVPlayerEngineContext*)(aResponse.GetContext());
1916 OSCL_ASSERT(nodecontext);
1917
1918 // Ignore other node completion if cancelling
1919 if (!iCmdToCancel.empty() || (CheckForPendingErrorHandlingCmd() && aResponse.GetCmdStatus() == PVMFErrCancelled))
1920 {
1921 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Node command completion ignored due to cancel process, id=%d", aResponse.GetCmdId()));
1922 // Remove the context from the list
1923 FreeEngineContext(nodecontext);
1924 return;
1925 }
1926
1927 // Process according to cmd type in the engine context data, node type, or engine state
1928 if (nodecontext->iCmdType == PVP_CMD_SinkNodeSkipMediaData)
1929 {
1930 HandleSinkNodeSkipMediaData(*nodecontext, aResponse);
1931 }
1932 else if (nodecontext->iCmdType == PVP_CMD_SinkNodeSkipMediaDataDuringPlayback)
1933 {
1934 HandleSinkNodeSkipMediaDataDuringPlayback(*nodecontext, aResponse);
1935 }
1936 else if (nodecontext->iCmdType == PVP_CMD_SinkNodeAutoPause)
1937 {
1938 HandleSinkNodePause(*nodecontext, aResponse);
1939 }
1940 else if (nodecontext->iCmdType == PVP_CMD_SinkNodeAutoResume)
1941 {
1942 HandleSinkNodeResume(*nodecontext, aResponse);
1943 }
1944 else if (nodecontext->iCmdType == PVP_CMD_DecNodeReset)
1945 {
1946 HandleDecNodeReset(*nodecontext, aResponse);
1947 }
1948 else if (nodecontext->iCmdType == PVP_CMD_SinkNodeReset)
1949 {
1950 HandleSinkNodeReset(*nodecontext, aResponse);
1951 }
1952 else if (nodecontext->iCmdType == PVP_CMD_GetNodeMetadataKey)
1953 {
1954 // Ignore the command status since it does not matter and continue going through the metadata interface list
1955
1956 // Determine the number of keys were added
1957 uint32 numkeysadded = iGetMetadataKeysParam.iKeyList->size() - iGetMetadataKeysParam.iNumKeyEntriesInList;
1958 if (numkeysadded > 0)
1959 {
1960 // Create an entry for the metadata key release list
1961 PVPlayerEngineMetadataReleaseEntry releaseentry;
1962 releaseentry.iMetadataIFListIndex = iGetMetadataKeysParam.iCurrentInterfaceIndex;
1963 // Save the start and end indices into the key list for keys that this node added
1964 releaseentry.iStartIndex = iGetMetadataKeysParam.iNumKeyEntriesInList;
1965 releaseentry.iEndIndex = iGetMetadataKeysParam.iNumKeyEntriesInList + numkeysadded - 1;
1966
1967 leavecode = 0;
1968 OSCL_TRY(leavecode, iMetadataKeyReleaseList.push_back(releaseentry));
1969 if (leavecode != 0)
1970 {
1971 // An element could not be added to the release list vector
1972 // so notify completion of GetMetadataKey() command with memory failure
1973 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, PVMFErrNoMemory);
1974
1975 // Release the last requested keys
1976 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[releaseentry.iMetadataIFListIndex].iInterface;
1977 OSCL_ASSERT(mdif != NULL);
1978 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), releaseentry.iStartIndex, releaseentry.iEndIndex);
1979
1980 // Release the memory allocated for rest of the metadata keys
1981 while (iMetadataKeyReleaseList.empty() == false)
1982 {
1983 mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
1984 OSCL_ASSERT(mdif != NULL);
1985 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
1986 iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
1987 }
1988
1989 // Remove the context from the list
1990 // Need to do this since we're calling return from here
1991 FreeEngineContext(nodecontext);
1992 return;
1993 }
1994
1995 // Update the variables tracking the key list
1996 if (iGetMetadataKeysParam.iNumKeyEntriesToFill != -1)
1997 {
1998 iGetMetadataKeysParam.iNumKeyEntriesToFill -= numkeysadded;
1999 }
2000 iGetMetadataKeysParam.iNumKeyEntriesInList += numkeysadded;
2001 }
2002
2003 // Update the interface index to the next one
2004 ++iGetMetadataKeysParam.iCurrentInterfaceIndex;
2005
2006 // Loop until GetNodeMetadataKeys() is called or command is completed
2007 bool endloop = false;
2008 while (endloop == false)
2009 {
2010 // Check if there is another metadata interface to check
2011 if (iGetMetadataKeysParam.iCurrentInterfaceIndex < iMetadataIFList.size())
2012 {
2013 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iInterface;
2014 OSCL_ASSERT(mdif != NULL);
2015 PVMFSessionId sessionid = iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iSessionId;
2016
2017 // Determine the number of keys available for the specified query key
2018 int32 numkeys = mdif->GetNumMetadataKeys(iGetMetadataKeysParam.iQueryKey);
2019 if (numkeys <= 0)
2020 {
2021 // Since there is no keys from this node, go to the next one
2022 ++iGetMetadataKeysParam.iCurrentInterfaceIndex;
2023 continue;
2024 }
2025
2026 // If more key entries can be added, retrieve from the node
2027 if (iGetMetadataKeysParam.iNumKeyEntriesToFill > 0 || iGetMetadataKeysParam.iNumKeyEntriesToFill == -1)
2028 {
2029 int32 leavecode = 0;
2030 PVMFCommandId cmdid = -1;
2031 PVPlayerEngineContext* newcontext = AllocateEngineContext(iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iEngineDatapath, iMetadataIFList[iGetMetadataKeysParam.iCurrentInterfaceIndex].iNode, NULL, nodecontext->iCmdId, nodecontext->iCmdContext, PVP_CMD_GetNodeMetadataKey);
2032 OSCL_TRY(leavecode, cmdid = mdif->GetNodeMetadataKeys(sessionid,
2033 *(iGetMetadataKeysParam.iKeyList),
2034 0,
2035 iGetMetadataKeysParam.iNumKeyEntriesToFill,
2036 iGetMetadataKeysParam.iQueryKey,
2037 (OsclAny*)newcontext));
2038 OSCL_FIRST_CATCH_ANY(leavecode,
2039 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() GetNodeMetadataKeys on a node did a leave!"));
2040 FreeEngineContext(newcontext);
2041 // Go to the next metadata IF in the list and continue
2042 ++iGetMetadataKeysParam.iCurrentInterfaceIndex;
2043 continue;);
2044
2045 // End the loop since GetNodeMetadataKeys() was called
2046 endloop = true;
2047 }
2048 else
2049 {
2050 // Retrieved the requested number of keys so notify completion of GetMetadataKey() command
2051 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
2052
2053 // Release the memory allocated for the metadata keys
2054 while (iMetadataKeyReleaseList.empty() == false)
2055 {
2056 mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
2057 OSCL_ASSERT(mdif != NULL);
2058 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
2059 iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
2060 }
2061
2062 // End the loop since finished command
2063 endloop = true;
2064 }
2065 }
2066 else
2067 {
2068 // No more so notify completion of GetMetadataKey() command
2069 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
2070
2071 // Release the memory allocated for the metadata keys
2072 while (iMetadataKeyReleaseList.empty() == false)
2073 {
2074 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
2075 OSCL_ASSERT(mdif != NULL);
2076 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
2077 iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
2078 }
2079
2080 // End the loop since reached the end of the metadata IF list
2081 endloop = true;
2082 }
2083 }
2084 }
2085 else if (nodecontext->iCmdType == PVP_CMD_GetNodeMetadataValue)
2086 {
2087 // Ignore the command status since it does not matter and continue going through the metadata interface list
2088
2089 // Determine the number of values were added
2090 uint32 numvaluesadded = iGetMetadataValuesParam.iValueList->size() - iGetMetadataValuesParam.iNumValueEntriesInList;
2091 if (numvaluesadded > 0)
2092 {
2093 // Create an entry for the metadata value release list
2094 PVPlayerEngineMetadataReleaseEntry releaseentry;
2095 releaseentry.iMetadataIFListIndex = iGetMetadataValuesParam.iCurrentInterfaceIndex;
2096 // Save the start and end indices into the value list for values that this node added
2097 releaseentry.iStartIndex = iGetMetadataValuesParam.iNumValueEntriesInList;
2098 releaseentry.iEndIndex = iGetMetadataValuesParam.iNumValueEntriesInList + numvaluesadded - 1;
2099
2100 leavecode = 0;
2101 OSCL_TRY(leavecode, iMetadataValueReleaseList.push_back(releaseentry));
2102 if (leavecode != 0)
2103 {
2104 // An element could not be added to the release list vector
2105 // so notify completion of GetMetadataValue() command with memory failure
2106 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, PVMFErrNoMemory);
2107
2108 // Release the last requested values
2109 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[releaseentry.iMetadataIFListIndex].iInterface;
2110 OSCL_ASSERT(mdif != NULL);
2111 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), releaseentry.iStartIndex, releaseentry.iEndIndex);
2112
2113 // Release the memory allocated for rest of the metadata values
2114 while (iMetadataValueReleaseList.empty() == false)
2115 {
2116 mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
2117 OSCL_ASSERT(mdif != NULL);
2118 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
2119 iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
2120 }
2121
2122 // Remove the context from the list
2123 // Need to do this since we're calling return from here
2124 FreeEngineContext(nodecontext);
2125 return;
2126 }
2127
2128 // Update the variables tracking the value list
2129 if (iGetMetadataValuesParam.iNumValueEntriesToFill != -1)
2130 {
2131 iGetMetadataValuesParam.iNumValueEntriesToFill -= numvaluesadded;
2132 }
2133 iGetMetadataValuesParam.iNumValueEntriesInList += numvaluesadded;
2134 }
2135
2136 // Update the interface index to the next one
2137 ++iGetMetadataValuesParam.iCurrentInterfaceIndex;
2138
2139 // Loop until GetNodeMetadataValues() is called or command is completed
2140 bool endloop = false;
2141 while (endloop == false)
2142 {
2143 // Check if there is another metadata interface to check
2144 if (iGetMetadataValuesParam.iCurrentInterfaceIndex < iMetadataIFList.size())
2145 {
2146 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iInterface;
2147 OSCL_ASSERT(mdif != NULL);
2148 PVMFSessionId sessionid = iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iSessionId;
2149
2150 // Determine the number of values available for the specified key list
2151 int32 numvalues = mdif->GetNumMetadataValues(*(iGetMetadataValuesParam.iKeyList));
2152 if (numvalues > 0)
2153 {
2154 // Add it to the total available
2155 *(iGetMetadataValuesParam.iNumAvailableValues) += numvalues;
2156 }
2157 else
2158 {
2159 // Since there is no values from this node, go to the next one
2160 ++iGetMetadataValuesParam.iCurrentInterfaceIndex;
2161 continue;
2162 }
2163
2164 // If more value entries can be added, retrieve from the node
2165 if (iGetMetadataValuesParam.iNumValueEntriesToFill > 0 || iGetMetadataValuesParam.iNumValueEntriesToFill == -1)
2166 {
2167 int32 leavecode = 0;
2168 PVMFCommandId cmdid = -1;
2169 PVPlayerEngineContext* newcontext = AllocateEngineContext(iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iEngineDatapath, iMetadataIFList[iGetMetadataValuesParam.iCurrentInterfaceIndex].iNode, NULL, nodecontext->iCmdId, nodecontext->iCmdContext, PVP_CMD_GetNodeMetadataValue);
2170 OSCL_TRY(leavecode, cmdid = mdif->GetNodeMetadataValues(sessionid,
2171 *(iGetMetadataValuesParam.iKeyList),
2172 *(iGetMetadataValuesParam.iValueList),
2173 0,
2174 iGetMetadataValuesParam.iNumValueEntriesToFill,
2175 (OsclAny*)newcontext));
2176 OSCL_FIRST_CATCH_ANY(leavecode,
2177 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() GetNodeMetadataValues on a node did a leave!"));
2178 FreeEngineContext(newcontext);
2179 // Go to the next metadata IF in the list and continue
2180 ++iGetMetadataValuesParam.iCurrentInterfaceIndex;
2181 continue;);
2182
2183 // End the loop since GetNodeMetadataValues() was called
2184 endloop = true;
2185 }
2186 else
2187 {
2188 // Retrieved requested number of values so notify completion of GetMetadataValue() command
2189 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
2190
2191 if (iMetadataValuesCopiedInCallBack)
2192 {
2193 // Release the memory allocated for the metadata values
2194 while (iMetadataValueReleaseList.empty() == false)
2195 {
2196 mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
2197 OSCL_ASSERT(mdif != NULL);
2198 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
2199 iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
2200 }
2201 }
2202 else
2203 {
2204 iReleaseMetadataValuesPending = true;
2205 }
2206
2207 // End the loop since finished command
2208 endloop = true;
2209 }
2210 }
2211 else
2212 {
2213 // No more so notify completion of GetMetadataValue() command
2214 EngineCommandCompleted(nodecontext->iCmdId, (OsclAny*)nodecontext->iCmdContext, aResponse.GetCmdStatus());
2215
2216 if (iMetadataValuesCopiedInCallBack)
2217 {
2218 // Release the memory allocated for the metadata values
2219 while (iMetadataValueReleaseList.empty() == false)
2220 {
2221 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
2222 OSCL_ASSERT(mdif != NULL);
2223 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
2224 iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
2225 }
2226 }
2227 else
2228 {
2229 iReleaseMetadataValuesPending = true;
2230 }
2231
2232 // End the loop since reached the end of the metadata IF list
2233 endloop = true;
2234 }
2235 }
2236 }
2237 else if (nodecontext->iNode == iSourceNode)
2238 {
2239 if (nodecontext->iCmdType == PVP_CMD_SourceNodeQueryDataSourcePositionDuringPlayback)
2240 {
2241 HandleSourceNodeQueryDataSourcePositionDuringPlayback(*nodecontext, aResponse);
2242 }
2243 else if (nodecontext->iCmdType == PVP_CMD_SourceNodeSetDataSourcePositionDuringPlayback)
2244 {
2245 HandleSourceNodeSetDataSourcePositionDuringPlayback(*nodecontext, aResponse);
2246 }
2247 else if (nodecontext->iCmdType == PVP_CMD_SourceNodeSetDataSourceDirection)
2248 {
2249 HandleSourceNodeSetDataSourceDirection(*nodecontext, aResponse);
2250 }
2251 else if (nodecontext->iCmdType == PVP_CMD_SourceNodeSetDataSourceRate)
2252 {
2253 HandleSourceNodeSetDataSourceRate(*nodecontext, aResponse);
2254 }
2255 else
2256 {
2257 switch (iState)
2258 {
2259 case PVP_ENGINE_STATE_IDLE:
2260 switch (nodecontext->iCmdType)
2261 {
2262 case PVP_CMD_SourceNodeQueryInitIF:
2263 HandleSourceNodeQueryInitIF(*nodecontext, aResponse);
2264 break;
2265
2266 case PVP_CMD_SourceNodeQueryTrackSelIF:
2267 HandleSourceNodeQueryTrackSelIF(*nodecontext, aResponse);
2268 break;
2269
2270 case PVP_CMD_SourceNodeQueryTrackLevelInfoIF:
2271 case PVP_CMD_SourceNodeQueryPBCtrlIF:
2272 case PVP_CMD_SourceNodeQueryDirCtrlIF:
2273 case PVP_CMD_SourceNodeQueryMetadataIF:
2274 case PVP_CMD_SourceNodeQueryCapConfigIF:
2275 case PVP_CMD_SourceNodeQueryCPMLicenseIF:
2276 case PVP_CMD_SourceNodeQuerySrcNodeRegInitIF:
2277 HandleSourceNodeQueryInterfaceOptional(*nodecontext, aResponse);
2278 break;
2279
2280 case PVP_CMD_SourceNodeGetLicense:
2281 HandleSourceNodeGetLicense(*nodecontext, aResponse);
2282 break;
2283
2284 case PVP_CMD_SourceNodeCancelGetLicense:
2285 HandleSourceNodeCancelGetLicense(*nodecontext, aResponse);
2286 break;
2287
2288 default:
2289 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_IDLE. Asserting"));
2290 OSCL_ASSERT(false);
2291 break;
2292 }
2293 break;
2294
2295 case PVP_ENGINE_STATE_INITIALIZED:
2296 switch (nodecontext->iCmdType)
2297 {
2298 case PVP_CMD_SourceNodeGetLicense:
2299 HandleSourceNodeGetLicense(*nodecontext, aResponse);
2300 break;
2301 default:
2302 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_IDLE. Asserting"));
2303 OSCL_ASSERT(false);
2304 break;
2305 }
2306 break;
2307
2308 case PVP_ENGINE_STATE_INITIALIZING:
2309 switch (nodecontext->iCmdType)
2310 {
2311 case PVP_CMD_SourceNodeInit:
2312 HandleSourceNodeInit(*nodecontext, aResponse);
2313 break;
2314
2315 case PVP_CMD_SourceNodeGetDurationValue:
2316 HandleSourceNodeGetDurationValue(*nodecontext, aResponse);
2317 break;
2318
2319 default:
2320 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_INITIALIZING. Asserting"));
2321 OSCL_ASSERT(false);
2322 break;
2323 }
2324 break;
2325
2326 case PVP_ENGINE_STATE_PREPARING:
2327 switch (nodecontext->iCmdType)
2328 {
2329 case PVP_CMD_SourceNodePrepare:
2330 HandleSourceNodePrepare(*nodecontext, aResponse);
2331 break;
2332
2333 case PVP_CMD_SourceNodeQueryDataSourcePosition:
2334 HandleSourceNodeQueryDataSourcePosition(*nodecontext, aResponse);
2335 break;
2336
2337 case PVP_CMD_SourceNodeSetDataSourcePosition:
2338 HandleSourceNodeSetDataSourcePosition(*nodecontext, aResponse);
2339 break;
2340
2341 case PVP_CMD_SourceNodeSetDataSourceDirection:
2342 //currently not allowed
2343 break;
2344
2345 case PVP_CMD_SourceNodeStart:
2346 HandleSourceNodeStart(*nodecontext, aResponse);
2347 break;
2348
2349 default:
2350 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_PREPARING. Asserting"));
2351 OSCL_ASSERT(false);
2352 break;
2353 }
2354 break;
2355
2356 case PVP_ENGINE_STATE_PAUSING:
2357 HandleSourceNodePause(*nodecontext, aResponse);
2358 break;
2359
2360 case PVP_ENGINE_STATE_RESUMING:
2361 switch (nodecontext->iCmdType)
2362 {
2363 case PVP_CMD_SourceNodeQueryDataSourcePosition:
2364 HandleSourceNodeQueryDataSourcePosition(*nodecontext, aResponse);
2365 break;
2366
2367 case PVP_CMD_SourceNodeSetDataSourcePosition:
2368 HandleSourceNodeSetDataSourcePosition(*nodecontext, aResponse);
2369 break;
2370
2371 case PVP_CMD_SourceNodeSetDataSourceDirection:
2372 HandleSourceNodeSetDataSourceDirection(*nodecontext, aResponse);
2373 break;
2374
2375 case PVP_CMD_SourceNodeStart:
2376 HandleSourceNodeResume(*nodecontext, aResponse);
2377 break;
2378
2379 default:
2380 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid source node command type in PVP_ENGINE_STATE_RESUMING. Asserting"));
2381 OSCL_ASSERT(false);
2382 break;
2383 }
2384 break;
2385
2386 case PVP_ENGINE_STATE_STOPPING:
2387 HandleSourceNodeStop(*nodecontext, aResponse);
2388 break;
2389
2390 case PVP_ENGINE_STATE_RESETTING:
2391 HandleSourceNodeReset(*nodecontext, aResponse);
2392 break;
2393
2394 default:
2395 break;
2396 }
2397 }
2398 }
2399 else if (iState == PVP_ENGINE_STATE_PREPARING)
2400 {
2401 switch (nodecontext->iCmdType)
2402 {
2403 case PVP_CMD_SinkNodeQueryCapConfigIF:
2404 HandleSinkNodeQueryCapConfigIF(*nodecontext, aResponse);
2405 break;
2406
2407 case PVP_CMD_SinkNodeInit:
2408 HandleSinkNodeInit(*nodecontext, aResponse);
2409 break;
2410
2411 case PVP_CMD_DecNodeQueryCapConfigIF:
2412 HandleDecNodeQueryCapConfigIF(*nodecontext, aResponse);
2413 break;
2414
2415 case PVP_CMD_DecNodeInit:
2416 HandleDecNodeInit(*nodecontext, aResponse);
2417 break;
2418
2419 case PVP_CMD_SinkNodeDecNodeReset:
2420 HandleSinkNodeDecNodeReset(*nodecontext, aResponse);
2421 break;
2422
2423 case PVP_CMD_SinkNodeQuerySyncCtrlIF:
2424 case PVP_CMD_SinkNodeQueryMetadataIF:
2425 HandleSinkNodeQueryInterfaceOptional(*nodecontext, aResponse);
2426 break;
2427
2428 case PVP_CMD_DecNodeQueryMetadataIF:
2429 HandleDecNodeQueryInterfaceOptional(*nodecontext, aResponse);
2430 break;
2431
2432 default:
2433 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Invalid node command type in PVP_ENGINE_STATE_PREPARING. Asserting"));
2434 OSCL_ASSERT(false);
2435 break;
2436 }
2437 }
2438 else
2439 {
2440 // Unknown node command completion. Assert
2441 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::NodeCommandCompleted() Unknown node command completion"));
2442 OSCL_ASSERT(false);
2443 }
2444
2445 // Remove the context from the list
2446 FreeEngineContext(nodecontext);
2447
2448 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::NodeCommandCompleted() Out"));
2449 }
2450
2451
HandleNodeInformationalEvent(const PVMFAsyncEvent & aEvent)2452 void PVPlayerEngine::HandleNodeInformationalEvent(const PVMFAsyncEvent& aEvent)
2453 {
2454 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeInformationalEvent() In"));
2455
2456 PVMFNodeInterface* nodeorigin = (PVMFNodeInterface*)(aEvent.GetContext());
2457
2458 PVPlayerNodeType nodetype = PVP_NODETYPE_UNKNOWN;
2459 int32 datapathindex = -1;
2460
2461 // Process the info event based on the node type reporting the event
2462 if (nodeorigin == iSourceNode)
2463 {
2464 HandleSourceNodeInfoEvent(aEvent);
2465 }
2466 else if (FindNodeTypeByNode(nodeorigin, nodetype, datapathindex) == true)
2467 {
2468 if (nodetype == PVP_NODETYPE_SINK)
2469 {
2470 HandleSinkNodeInfoEvent(aEvent, datapathindex);
2471 }
2472 else if (nodetype == PVP_NODETYPE_DECODER)
2473 {
2474 HandleDecNodeInfoEvent(aEvent, datapathindex);
2475 }
2476 else
2477 {
2478 // Event from unknown node or component. Do nothing but log it
2479 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",
2480 aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
2481 }
2482 }
2483 else
2484 {
2485 // Event from unknown node or component. Do nothing but log it
2486 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",
2487 aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
2488 }
2489
2490 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeInformationalEvent() Out"));
2491 }
2492
2493
HandleNodeErrorEvent(const PVMFAsyncEvent & aEvent)2494 void PVPlayerEngine::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent)
2495 {
2496 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeErrorEvent() In"));
2497
2498 PVMFNodeInterface* nodeorigin = (PVMFNodeInterface*)(aEvent.GetContext());
2499
2500 PVPlayerNodeType nodetype = PVP_NODETYPE_UNKNOWN;
2501 int32 datapathindex = -1;
2502
2503 // Process the error event based on the node type reporting the event
2504 if (nodeorigin == iSourceNode)
2505 {
2506 HandleSourceNodeErrorEvent(aEvent);
2507 }
2508 else if (FindNodeTypeByNode(nodeorigin, nodetype, datapathindex) == true)
2509 {
2510 if (nodetype == PVP_NODETYPE_SINK)
2511 {
2512 HandleSinkNodeErrorEvent(aEvent, datapathindex);
2513 }
2514 else if (nodetype == PVP_NODETYPE_DECODER)
2515 {
2516 HandleDecNodeErrorEvent(aEvent, datapathindex);
2517 }
2518 else
2519 {
2520 // Event from unknown node or component. Do nothing but log it
2521 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",
2522 aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
2523 }
2524 }
2525 else
2526 {
2527 // Event from unknown node or component. Do nothing but log it
2528 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",
2529 aEvent.GetEventType(), aEvent.GetContext(), aEvent.GetEventData()));
2530 }
2531
2532 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleNodeErrorEvent() Out"));
2533 }
2534
RemoveDatapathContextFromList()2535 void PVPlayerEngine::RemoveDatapathContextFromList()
2536 {
2537 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDatapathContextFromList(): Erasing from ContextList iCurrentContextList.size() in : %d",
2538 iCurrentContextList.size()));
2539 for (int32 i = iCurrentContextList.size() - 1; i >= 0; --i)
2540 {
2541 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDatapathContextFromList(): iCurrentContextList[i]->iCmdType %d",
2542 iCurrentContextList[i]->iCmdType));
2543
2544 switch (iCurrentContextList[i]->iCmdType)
2545 {
2546 case PVP_CMD_DPPrepare:
2547 case PVP_CMD_DPStart:
2548 case PVP_CMD_DPStop:
2549 case PVP_CMD_DPTeardown:
2550 case PVP_CMD_DPReset:
2551 FreeEngineContext(iCurrentContextList[i]);
2552 break;
2553 default:
2554 break;
2555 }
2556 }
2557 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDatapathContextFromList(): iCurrentContextList.size() out : %d",
2558 iCurrentContextList.size()));
2559 }
2560
2561
HandlePlayerDatapathEvent(int32,PVMFStatus aEventStatus,OsclAny * aContext,PVMFCmdResp * aCmdResp)2562 void PVPlayerEngine::HandlePlayerDatapathEvent(int32 /*aDatapathEvent*/, PVMFStatus aEventStatus, OsclAny* aContext, PVMFCmdResp* aCmdResp)
2563 {
2564 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() In"));
2565
2566 // Check if a cancel command completed
2567 uint32* context_uint32 = (uint32*)aContext;
2568 if (context_uint32 == &iNumberCancelCmdPending)
2569 {
2570 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Cancel in datapath completed for cancel command. Pending %d", iNumberCancelCmdPending));
2571 --iNumberCancelCmdPending;
2572 if (iNumberCancelCmdPending == 0)
2573 {
2574 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Cancelling of all node/datapath commands complete, now reset all nodes"));
2575 // Clear the CancelCmd queue as the cmd has been cancelled.
2576 iCmdToCancel.clear();
2577
2578 RemoveDatapathContextFromList(); // empty left over contexts from cancelled datapath commands
2579 // Now reset the source node
2580 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
2581
2582 PVMFCommandId cmdid = -1;
2583 int32 leavecode = 0;
2584 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
2585 OSCL_FIRST_CATCH_ANY(leavecode,
2586
2587 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Reset on iSourceNode did a leave!"));
2588 FreeEngineContext(context);
2589 OSCL_ASSERT(false);
2590 return);
2591
2592 SetEngineState(PVP_ENGINE_STATE_RESETTING);
2593 }
2594 return;
2595 }
2596
2597 PVPlayerEngineContext* datapathcontext = (PVPlayerEngineContext*)aContext;
2598 OSCL_ASSERT(datapathcontext);
2599
2600 // Ignore other datapath event if cancelling
2601 if (!iCmdToCancel.empty() || (CheckForPendingErrorHandlingCmd() && (aCmdResp && aCmdResp->GetCmdStatus() == PVMFErrCancelled)))
2602 {
2603 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Datapath event ignored due to cancel process"));
2604 // Remove the context from the list
2605 FreeEngineContext(datapathcontext);
2606 return;
2607 }
2608
2609 // Process the datapath event based on the engine state
2610 if (iState == PVP_ENGINE_STATE_PREPARING)
2611 {
2612 switch (datapathcontext->iCmdType)
2613 {
2614 case PVP_CMD_DPPrepare:
2615 HandleDatapathPrepare(*datapathcontext, aEventStatus, aCmdResp);
2616 break;
2617
2618 case PVP_CMD_DPStart:
2619 HandleDatapathStart(*datapathcontext, aEventStatus, aCmdResp);
2620 break;
2621
2622 default:
2623 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid datapath command type in PVP_ENGINE_STATE_PREPARING."));
2624 break;
2625 }
2626 }
2627 else if (iState == PVP_ENGINE_STATE_PAUSING)
2628 {
2629 HandleDatapathPause(*datapathcontext, aEventStatus, aCmdResp);
2630 }
2631 else if (iState == PVP_ENGINE_STATE_RESUMING)
2632 {
2633 HandleDatapathResume(*datapathcontext, aEventStatus, aCmdResp);
2634 }
2635 else if (iState == PVP_ENGINE_STATE_STOPPING)
2636 {
2637 switch (datapathcontext->iCmdType)
2638 {
2639 case PVP_CMD_DPStop:
2640 HandleDatapathStop(*datapathcontext, aEventStatus, aCmdResp);
2641 break;
2642
2643 case PVP_CMD_DPTeardown:
2644 HandleDatapathTeardown(*datapathcontext, aEventStatus, aCmdResp);
2645 break;
2646
2647 case PVP_CMD_DPReset:
2648 HandleDatapathReset(*datapathcontext, aEventStatus, aCmdResp);
2649 break;
2650
2651 default:
2652 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid datapath command type in PVP_ENGINE_STATE_STOPPING."));
2653 break;
2654 }
2655 }
2656 else if (iState == PVP_ENGINE_STATE_RESETTING)
2657 {
2658 switch (datapathcontext->iCmdType)
2659 {
2660 case PVP_CMD_DPReset:
2661 HandleDatapathReset(*datapathcontext, aEventStatus, aCmdResp);
2662 break;
2663
2664 default:
2665 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid datapath command type in PVP_ENGINE_STATE_RESETTING"));
2666 break;
2667 }
2668 }
2669 else
2670 {
2671 // Unknown datapath.
2672 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Invalid state for datapath command completion."));
2673 }
2674
2675 // Remove the context from the list
2676 FreeEngineContext(datapathcontext);
2677
2678 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandlePlayerDatapathEvent() Out"));
2679 }
2680
NotificationsInterfaceDestroyed()2681 void PVPlayerEngine::NotificationsInterfaceDestroyed()
2682 {
2683 iClockNotificationsInf = NULL;
2684 }
2685
ProcessCallBack(uint32 aCallBackID,PVTimeComparisonUtils::MediaTimeStatus aTimerAccuracy,uint32 aDelta,const OsclAny * acontextData,PVMFStatus aStatus)2686 void PVPlayerEngine::ProcessCallBack(uint32 aCallBackID, PVTimeComparisonUtils::MediaTimeStatus aTimerAccuracy, uint32 aDelta,
2687 const OsclAny* acontextData, PVMFStatus aStatus)
2688 {
2689 OSCL_UNUSED_ARG(aTimerAccuracy);
2690 OSCL_UNUSED_ARG(aDelta);
2691 OSCL_UNUSED_ARG(acontextData);
2692
2693 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::TimeoutOccurred() Timer for PlayStatus event triggered"));
2694
2695 if (aCallBackID == iPlayStatusCallbackTimerID)
2696 {
2697 //Callback timer needs to be restarted if status is success
2698 if ((PVMFSuccess == aStatus) && iPlayStatusTimerEnabled)
2699 {
2700 SendPositionStatusUpdate();
2701 iPlayStatusTimerEnabled = false;
2702 iPlayStatusCallbackTimerID = 0;
2703
2704 StartPlaybackStatusTimer();
2705 }
2706 else
2707 {
2708 if (aStatus == PVMFErrCallbackClockStopped)
2709 {
2710 iPlayStatusTimerEnabled = false;
2711 iPlayStatusCallbackTimerID = 0;
2712 }
2713 }
2714 }
2715 }
SendPositionStatusUpdate(void)2716 void PVPlayerEngine::SendPositionStatusUpdate(void)
2717 {
2718 PVPPlaybackPosition curpos;
2719 curpos.iPosUnit = iPBPosStatusUnit;
2720 GetPlaybackClockPosition(curpos);
2721
2722 uint8 poslocalbuffer[8];
2723 oscl_memset(poslocalbuffer, 0, 8);
2724 poslocalbuffer[0] = 1;
2725 switch (iPBPosStatusUnit)
2726 {
2727 case PVPPBPOSUNIT_SEC:
2728 oscl_memcpy(&poslocalbuffer[4], &(curpos.iPosValue.sec_value), sizeof(uint32));
2729 break;
2730
2731 case PVPPBPOSUNIT_MIN:
2732 oscl_memcpy(&poslocalbuffer[4], &(curpos.iPosValue.min_value), sizeof(uint32));
2733 break;
2734
2735 case PVPPBPOSUNIT_MILLISEC:
2736 default:
2737 oscl_memcpy(&poslocalbuffer[4], &(curpos.iPosValue.millisec_value), sizeof(uint32));
2738 break;
2739 }
2740
2741 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
2742 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackPositionStatus, puuid, NULL));
2743 // EventData parameter will be deprecated, and curpos will not be sent through EventData in future.
2744 SendInformationalEvent(PVMFInfoPositionStatus, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&curpos, poslocalbuffer, 8);
2745 infomsg->removeRef();
2746 }
2747
2748
TimeoutOccurred(int32 timerID,int32)2749 void PVPlayerEngine::TimeoutOccurred(int32 timerID, int32 /*timeoutInfo*/)
2750 {
2751 if (timerID == PVPLAYERENGINE_TIMERID_ENDTIMECHECK)
2752 {
2753 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::TimeoutOccurred() Timer for EndTime check triggered"));
2754
2755 PVPPlaybackPosition curpos;
2756 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
2757 GetPlaybackClockPosition(curpos);
2758
2759 if (iCurrentEndPosition.iIndeterminate || iCurrentEndPosition.iPosUnit != PVPPBPOSUNIT_MILLISEC)
2760 {
2761 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::TimeoutOccurred() End time unit is invalid. Disabling end time check."));
2762 iEndTimeCheckEnabled = false;
2763 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
2764 OSCL_ASSERT(false);
2765 return;
2766 }
2767
2768 if (curpos.iPosValue.millisec_value >= iCurrentEndPosition.iPosValue.millisec_value)
2769 {
2770 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::TimeoutOccurred() Specified end time reached so issuing pause command"));
2771
2772 iEndTimeCheckEnabled = false;
2773 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
2774 // Issues end time reached command
2775 AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED, NULL, NULL, NULL, false);
2776 }
2777 else if (!iEndTimeCheckEnabled)
2778 {
2779 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
2780 }
2781 }
2782 }
2783
RecognizeCompleted(PVMFFormatType aSourceFormatType,OsclAny * aContext)2784 void PVPlayerEngine::RecognizeCompleted(PVMFFormatType aSourceFormatType, OsclAny* aContext)
2785 {
2786 // Check if a cancel command completed
2787 uint32* context_uint32 = (uint32*)(aContext);
2788 if (context_uint32 == &iNumberCancelCmdPending)
2789 {
2790 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RecognizeCompleted() Recognize request cancelled"));
2791 --iNumberCancelCmdPending;
2792 if (iNumberCancelCmdPending == 0)
2793 {
2794 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RecognizeCompleted() Cancelling of all node/datapath commands complete, now reset all nodes"));
2795 // Clear the CancelCmd queue as the cmd has been cancelled.
2796 iCmdToCancel.clear();
2797
2798 RemoveDatapathContextFromList(); // empty left over contexts from cancelled datapath commands
2799 // Now reset the source node
2800 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
2801
2802 PVMFCommandId cmdid = -1;
2803 int32 leavecode = 0;
2804 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
2805 OSCL_FIRST_CATCH_ANY(leavecode,
2806
2807 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RecognizeCompleted() Reset on iSourceNode did a leave!"));
2808 FreeEngineContext(context);
2809 OSCL_ASSERT(false);
2810 return);
2811
2812 SetEngineState(PVP_ENGINE_STATE_RESETTING);
2813 }
2814 return;
2815 }
2816
2817 // Ignore recognize completion if cancelling
2818 if (!iCmdToCancel.empty() || CheckForPendingErrorHandlingCmd())
2819 {
2820 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RecognizeCompleted() Recognize completion ignored due to cancel process"));
2821 // Remove the context from the list
2822 FreeEngineContext((PVPlayerEngineContext*)(aContext));
2823 return;
2824 }
2825
2826 // Save the recognized source format
2827 iSourceFormatType = aSourceFormatType;
2828
2829 // Free the engine context after saving the cmd id and context
2830 PVPlayerEngineContext* reccontext = (PVPlayerEngineContext*)(aContext);
2831 OSCL_ASSERT(reccontext != NULL);
2832 PVCommandId cmdid = reccontext->iCmdId;
2833 OsclAny* cmdcontext = reccontext->iCmdContext;
2834 FreeEngineContext(reccontext);
2835
2836 // Start the source node creation and setup sequence
2837 PVMFStatus retval = DoSetupSourceNode(cmdid, cmdcontext);
2838
2839 if (retval != PVMFSuccess)
2840 {
2841 bool ehPending = CheckForPendingErrorHandlingCmd();
2842 if (ehPending)
2843 {
2844 // there should be no error handling queued.
2845 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RecognizeCompleted() Already EH pending, should never happen"));
2846 return;
2847 }
2848 else
2849 {
2850 // Queue up Error Handling
2851 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::RecognizeCompleted() DoSetupSourceNode failed, Add EH command"));
2852 iCommandCompleteStatusInErrorHandling = retval;
2853 iCommandCompleteErrMsgInErrorHandling = NULL;
2854 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
2855 }
2856 return;
2857 }
2858 }
2859
2860 //A callback from the threadsafe queue
ThreadSafeQueueDataAvailable(ThreadSafeQueue * aQueue)2861 void PVPlayerEngine::ThreadSafeQueueDataAvailable(ThreadSafeQueue* aQueue)
2862 {
2863 OSCL_UNUSED_ARG(aQueue);
2864
2865 //pull all available data off the thread-safe queue and transfer
2866 //it to the internal queue.
2867 for (uint32 ndata = 1; ndata;)
2868 {
2869 ThreadSafeQueueId id;
2870 OsclAny* data;
2871 ndata = iThreadSafeQueue.DeQueue(id, data);
2872 if (ndata)
2873 {
2874 PVPlayerEngineCommand* cmd = (PVPlayerEngineCommand*)data;
2875 AddCommandToQueue(cmd->iCmdType
2876 , cmd->iContextData
2877 , &cmd->iParamVector
2878 , &cmd->iUuid
2879 , true//assume all out-of-thread data is an API command.
2880 , (PVCommandId*)&id);//use the command ID that was returned to the caller.
2881 OSCL_DELETE(cmd);
2882 }
2883 }
2884 }
2885
DoOOTSyncCommand(int32 aCmdType,Oscl_Vector<PVPlayerEngineCommandParamUnion,OsclMemAllocator> * aParamVector,const PVUuid * aUuid)2886 PVMFStatus PVPlayerEngine::DoOOTSyncCommand(int32 aCmdType,
2887 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator>* aParamVector,
2888 const PVUuid* aUuid)
2889 {
2890 //Called from out-of-thread to perform a synchronous command
2891
2892
2893 //Add a PVMFStatus* to the end of the command param vec to hold the result.
2894 PVMFStatus status;
2895 PVPlayerEngineCommandParamUnion param;
2896 param.pOsclAny_value = (OsclAny*) & status;
2897 aParamVector->push_back(param);
2898
2899 //push the command across the thread boundary
2900 PVCommandId id = 0;
2901 PVPlayerEngineCommand* cmd = OSCL_NEW(PVPlayerEngineCommand, (aCmdType, id, NULL, aParamVector));
2902 if (aUuid)
2903 cmd->SetUuid(*aUuid);
2904 iThreadSafeQueue.AddToQueue(cmd);
2905
2906 //block and wait for completion by engine thread.
2907 iOOTSyncCommandSem.Wait();
2908 return status;
2909 }
2910
OOTSyncCommandComplete(PVPlayerEngineCommand & aCmd,PVMFStatus aStatus)2911 void PVPlayerEngine::OOTSyncCommandComplete(PVPlayerEngineCommand& aCmd, PVMFStatus aStatus)
2912 {
2913 //Called in engine thread to complete an out-of-thread synchronous command
2914
2915 //Put the result status into the last element of the command param vector.
2916 PVMFStatus* status = (PVMFStatus*)(aCmd.GetParam(aCmd.iParamVector.size() - 1).pOsclAny_value);
2917 OSCL_ASSERT(status);
2918 *status = aStatus;
2919
2920 //Signal the calling thread.
2921 iOOTSyncCommandSem.Signal();
2922 }
2923
AddCommandToQueue(int32 aCmdType,OsclAny * aContextData,Oscl_Vector<PVPlayerEngineCommandParamUnion,OsclMemAllocator> * aParamVector,const PVUuid * aUuid,bool aAPICommand,PVCommandId * aId)2924 PVCommandId PVPlayerEngine::AddCommandToQueue(int32 aCmdType, OsclAny* aContextData,
2925 Oscl_Vector<PVPlayerEngineCommandParamUnion, OsclMemAllocator>* aParamVector,
2926 const PVUuid* aUuid, bool aAPICommand, PVCommandId* aId)
2927 {
2928 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::AddCommandToQueue() In CmdType %d, CmdId %d", aCmdType, iCommandId));
2929
2930 PVCommandId commandId;
2931 if (aId)
2932 {
2933 //This command is being transferred from the thread-safe queue to the
2934 //internal queue, in engine thread context.
2935 //The input ID is the one that was returned to the
2936 //caller, so use that ID instead of generating a new one.
2937 commandId = *aId;
2938 }
2939 else
2940 {
2941 //Generate the next command ID, being careful to avoid thread contention
2942 //for "iCommandId".
2943 iCommandIdMut.Lock();
2944 commandId = iCommandId;
2945 ++iCommandId;
2946 if (iCommandId == 0x7FFFFFFF)
2947 {
2948 iCommandId = 0;
2949 }
2950 iCommandIdMut.Unlock();
2951
2952 //If this is from outside engine thread context, then push the command across the
2953 //thread boundary.
2954 if (!iThreadSafeQueue.IsInThread())
2955 {
2956 PVPlayerEngineCommand* cmd = OSCL_NEW(PVPlayerEngineCommand, (aCmdType, commandId, aContextData, aParamVector, aAPICommand));
2957 if (aUuid)
2958 cmd->SetUuid(*aUuid);
2959 iThreadSafeQueue.AddToQueue(cmd, (ThreadSafeQueueId*)&commandId);
2960 return commandId;
2961 }
2962 }
2963
2964 PVPlayerEngineCommand cmd(aCmdType, commandId, aContextData, aParamVector, aAPICommand);
2965 if (aUuid)
2966 {
2967 cmd.SetUuid(*aUuid);
2968 }
2969
2970 int32 leavecode = 0;
2971 OSCL_TRY(leavecode, iPendingCmds.push(cmd));
2972 OSCL_FIRST_CATCH_ANY(leavecode,
2973 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::AddCommandToQueue() Adding command to pending command list did a leave!"));
2974 OSCL_ASSERT(false);
2975 return -1;);
2976
2977 // if engine needs to queue any error handling command set the engine state as PVP_ENGINE_STATE_ERROR.
2978 switch (aCmdType)
2979 {
2980 case PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE:
2981 case PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT:
2982 case PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE:
2983 case PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE:
2984 case PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME:
2985 case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE:
2986 case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE:
2987 case PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP:
2988 case PVP_ENGINE_COMMAND_ERROR_HANDLING_CANCEL_ALL_COMMANDS:
2989 case PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL:
2990 SetEngineState(PVP_ENGINE_STATE_ERROR);
2991 SendInformationalEvent(PVMFInfoErrorHandlingStart, NULL);
2992 break;
2993
2994 default:
2995 break;
2996 }
2997
2998 RunIfNotReady();
2999
3000 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
3001 (0, "PVPlayerEngine::AddCommandToQueue() Type=%d ID=%d APIcmd=%d Tick=%d",
3002 aCmdType, cmd.GetCmdId(), aAPICommand, OsclTickCount::TickCount()));
3003
3004 return cmd.GetCmdId();
3005 }
3006
3007
SetEngineState(PVPlayerEngineState aState)3008 void PVPlayerEngine::SetEngineState(PVPlayerEngineState aState)
3009 {
3010 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SetEngineState() In Current state %d, New state %d", iState, aState));
3011 iState = aState;
3012 }
3013
3014
GetPVPlayerState(void)3015 PVPlayerState PVPlayerEngine::GetPVPlayerState(void)
3016 {
3017 switch (iState)
3018 {
3019 case PVP_ENGINE_STATE_IDLE:
3020 case PVP_ENGINE_STATE_INITIALIZING:
3021 return PVP_STATE_IDLE;
3022
3023 case PVP_ENGINE_STATE_INITIALIZED:
3024 case PVP_ENGINE_STATE_PREPARING:
3025 case PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE:
3026 case PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE:
3027 case PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE:
3028 return PVP_STATE_INITIALIZED;
3029
3030 case PVP_ENGINE_STATE_PREPARED:
3031 case PVP_ENGINE_STATE_STARTING:
3032 return PVP_STATE_PREPARED;
3033
3034 case PVP_ENGINE_STATE_STARTED:
3035 case PVP_ENGINE_STATE_AUTO_PAUSING:
3036 case PVP_ENGINE_STATE_AUTO_PAUSED:
3037 case PVP_ENGINE_STATE_AUTO_RESUMING:
3038 case PVP_ENGINE_STATE_PAUSING:
3039 case PVP_ENGINE_STATE_STOPPING:
3040 return PVP_STATE_STARTED;
3041
3042 case PVP_ENGINE_STATE_PAUSED:
3043 case PVP_ENGINE_STATE_RESUMING:
3044 return PVP_STATE_PAUSED;
3045
3046 case PVP_ENGINE_STATE_RESETTING:
3047 {
3048 bool ehPending = CheckForPendingErrorHandlingCmd();
3049 if (ehPending)
3050 {
3051 return PVP_STATE_ERROR;
3052 }
3053 else
3054 {
3055 return PVP_STATE_IDLE;
3056 }
3057 }
3058
3059 case PVP_ENGINE_STATE_ERROR:
3060 return PVP_STATE_ERROR;
3061
3062 default:
3063 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetPVPlayerState() Unknown engine state. Asserting"));
3064 OSCL_ASSERT(false);
3065 break;
3066 }
3067
3068 return PVP_STATE_ERROR;
3069 }
3070
3071
GetPlaybackClockPosition(PVPPlaybackPosition & aClockPos)3072 void PVPlayerEngine::GetPlaybackClockPosition(PVPPlaybackPosition& aClockPos)
3073 {
3074 bool tmpbool = false;
3075 uint32 clockcurpos = 0;
3076 aClockPos.iIndeterminate = false;
3077
3078 int32 nptcurpos;
3079
3080 if (!iChangeDirectionNPT.iIndeterminate)
3081 {
3082 // report the expected NPT after the direction change
3083 // to avoid weird transient values between the direction change
3084 // and the repositioning completion.
3085 nptcurpos = iChangeDirectionNPT.iPosValue.millisec_value;
3086 }
3087 else
3088 {
3089 // Get current playback clock position
3090 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
3091
3092 nptcurpos = iStartNPT + iPlaybackDirection * (clockcurpos - iStartMediaDataTS);
3093 }
3094 if (nptcurpos < 0)
3095 {
3096 nptcurpos = 0;
3097 }
3098
3099 if (ConvertFromMillisec((uint32)nptcurpos, aClockPos) != PVMFSuccess)
3100 {
3101 // Other position units are not supported yet
3102 aClockPos.iIndeterminate = true;
3103 }
3104 }
3105
3106
ConvertToMillisec(PVPPlaybackPosition & aPBPos,uint32 & aTimeMS)3107 PVMFStatus PVPlayerEngine::ConvertToMillisec(PVPPlaybackPosition& aPBPos, uint32& aTimeMS)
3108 {
3109 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertToMillisec() In"));
3110
3111 if (aPBPos.iIndeterminate)
3112 {
3113 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertToMillisec() Indeterminate position"));
3114 return PVMFErrArgument;
3115 }
3116
3117 bool owallclockunits = false;
3118 switch (aPBPos.iPosUnit)
3119 {
3120 case PVPPBPOSUNIT_MILLISEC:
3121 aTimeMS = aPBPos.iPosValue.millisec_value;
3122 owallclockunits = true;
3123 break;
3124
3125 case PVPPBPOSUNIT_SEC:
3126 aTimeMS = aPBPos.iPosValue.sec_value * 1000;
3127 owallclockunits = true;
3128 break;
3129
3130 case PVPPBPOSUNIT_MIN:
3131 aTimeMS = aPBPos.iPosValue.min_value * 60000;
3132 owallclockunits = true;
3133 break;
3134
3135 case PVPPBPOSUNIT_HOUR:
3136 aTimeMS = aPBPos.iPosValue.hour_value * 3600000;
3137 owallclockunits = true;
3138 break;
3139
3140 case PVPPBPOSUNIT_SMPTE:
3141 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() SMPTE not supported yet"));
3142 return PVMFErrArgument;
3143
3144 case PVPPBPOSUNIT_PERCENT:
3145 {
3146 if (iSourceDurationAvailable == false)
3147 {
3148 // Duration info not available from source node so can't convert
3149 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Duration not available so can't convert"));
3150 return PVMFErrArgument;
3151 }
3152
3153 if (iSourceDurationInMS == 0)
3154 {
3155 // Duration is 0 so can't convert
3156 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Duration value is 0 so can't convert"));
3157 return PVMFErrArgument;
3158 }
3159
3160 if (aPBPos.iPosValue.percent_value >= 100)
3161 {
3162 // If percentage greater than 100, cap to 100%
3163 aTimeMS = iSourceDurationInMS;
3164 }
3165 else
3166 {
3167 // Calculate time in millseconds based on percentage of duration
3168 aTimeMS = (aPBPos.iPosValue.percent_value * iSourceDurationInMS) / 100;
3169 }
3170 }
3171 break;
3172
3173 case PVPPBPOSUNIT_SAMPLENUMBER:
3174 {
3175 if (iSourceNodeTrackLevelInfoIF == NULL)
3176 {
3177 // The source node doesn't have the query IF to convert samplenum to time
3178 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Sample number to time conversion not available"));
3179 return PVMFErrArgument;
3180 }
3181
3182 // Determine which track to use for conversion.
3183 // Give preference to video track, then text, and finally audio
3184 PVMFTrackInfo* track = NULL;
3185 int32 datapathIndex = -1;
3186
3187 // Search from the datapath list.
3188 // 1) Try for video track
3189 bool retVal = FindDatapathForTrackUsingMimeString(true, false, false, datapathIndex);
3190 if (retVal == false)
3191 {
3192 // Video track not available, look for text track
3193 retVal = FindDatapathForTrackUsingMimeString(false, false, true, datapathIndex);
3194 if (retVal == false)
3195 {
3196 // Text track also not avaliable, look for audio track
3197 retVal = FindDatapathForTrackUsingMimeString(false, true, false, datapathIndex);
3198 if (retVal == false)
3199 {
3200 // Track is not available to do the conversion
3201 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Track not selected for conversion"));
3202 return PVMFErrArgument;
3203 }
3204 }
3205 }
3206
3207 // Track avalaible.
3208 track = iDatapathList[datapathIndex].iTrackInfo;
3209
3210 // Convert the sample number to time in milliseconds
3211 PVMFTimestamp framets = 0;
3212 if (iSourceNodeTrackLevelInfoIF->GetTimestampForSampleNumber(*track, aPBPos.iPosValue.samplenum_value, framets) != PVMFSuccess)
3213 {
3214 // Conversion failed
3215 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Sample number to time conversion failed"));
3216 return PVMFErrArgument;
3217 }
3218
3219 aTimeMS = framets;
3220 }
3221 break;
3222
3223 case PVPPBPOSUNIT_DATAPOSITION:
3224 {
3225 if (iSourceNodeTrackLevelInfoIF == NULL)
3226 {
3227 // The source node doesn't have the ext IF to convert data position to time
3228 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Data position to time conversion not available"));
3229 return PVMFErrArgument;
3230 }
3231
3232 // Go through each active track and find the minimum time for given data position
3233 bool mintsvalid = false;
3234 PVMFTimestamp mints = 0xFFFFFFFF;
3235 for (uint32 i = 0; i < iDatapathList.size(); ++i)
3236 {
3237 if (iDatapathList[i].iDatapath)
3238 {
3239 PVMFTimestamp curts = 0;
3240 if (iSourceNodeTrackLevelInfoIF->GetTimestampForDataPosition(*(iDatapathList[i].iTrackInfo), aPBPos.iPosValue.datapos_value, curts) != PVMFSuccess)
3241 {
3242 // Conversion failed
3243 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Data position to time conversion failed"));
3244 }
3245 else
3246 {
3247 // Conversion succeeded. Save only if it is the minimum encountered so far.
3248 mintsvalid = true;
3249 if (curts < mints)
3250 {
3251 mints = curts;
3252 }
3253 }
3254 }
3255 }
3256
3257 if (mintsvalid == false)
3258 {
3259 // Conversion on all active tracks failed
3260 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Data position to time conversion could not be done on any active track"));
3261 return PVMFErrArgument;
3262 }
3263
3264 aTimeMS = mints;
3265 }
3266 break;
3267
3268 case PVPPBPOSUNIT_PLAYLIST:
3269 {
3270 switch (aPBPos.iPlayListPosUnit)
3271 {
3272 case PVPPBPOSUNIT_MILLISEC:
3273 aTimeMS = aPBPos.iPlayListPosValue.millisec_value;
3274 break;
3275
3276 case PVPPBPOSUNIT_SEC:
3277 aTimeMS = aPBPos.iPlayListPosValue.sec_value * 1000;
3278 break;
3279
3280 case PVPPBPOSUNIT_MIN:
3281 aTimeMS = aPBPos.iPlayListPosValue.min_value * 60000;
3282 break;
3283
3284 case PVPPBPOSUNIT_HOUR:
3285 aTimeMS = aPBPos.iPlayListPosValue.hour_value * 3600000;
3286 break;
3287
3288 default:
3289 // Don't support the other units for now
3290 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Unsupported playlist position units"));
3291 return PVMFErrArgument;
3292 }
3293 }
3294 break;
3295
3296 default:
3297 // Don't support the other units for now
3298 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Unsupported position units"));
3299 return PVMFErrArgument;
3300 }
3301
3302 if (owallclockunits == true)
3303 {
3304 if ((aTimeMS > iSourceDurationInMS) && (iSourceDurationAvailable == true))
3305 {
3306 //cap time to clip duration
3307 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVPlayerEngine::ConvertToMillisec() Capping value - Acutal=%d, CappedValue=%d",
3308 aTimeMS, iSourceDurationInMS));
3309 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_DEBUG, (0, "PVPlayerEngine::ConvertToMillisec() Capping value - Acutal=%d, CappedValue=%d",
3310 aTimeMS, iSourceDurationInMS));
3311 aTimeMS = iSourceDurationInMS;
3312 }
3313 else
3314 {
3315 // just pass the converted time even if duration is not available and let
3316 // source node handle the request.
3317 }
3318 }
3319
3320 if (aPBPos.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
3321 {
3322 aPBPos.iPlayListPosValue.millisec_value = aTimeMS;
3323 aPBPos.iPlayListPosUnit = PVPPBPOSUNIT_MILLISEC;
3324 }
3325 else
3326 {
3327 aPBPos.iPosValue.millisec_value = aTimeMS;
3328 aPBPos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
3329 }
3330 iTargetNPT = aTimeMS;
3331
3332 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ConvertToMillisec() Out"));
3333 return PVMFSuccess;
3334 }
3335
3336
ConvertFromMillisec(uint32 aTimeMS,PVPPlaybackPosition & aPBPos)3337 PVMFStatus PVPlayerEngine::ConvertFromMillisec(uint32 aTimeMS, PVPPlaybackPosition& aPBPos)
3338 {
3339 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ConvertFromMillisec() In"));
3340
3341 // Convert to specified time units
3342 switch (aPBPos.iPosUnit)
3343 {
3344 case PVPPBPOSUNIT_MILLISEC:
3345 aPBPos.iPosValue.millisec_value = aTimeMS;
3346 break;
3347
3348 case PVPPBPOSUNIT_SEC:
3349 aPBPos.iPosValue.sec_value = aTimeMS / 1000;
3350 break;
3351
3352 case PVPPBPOSUNIT_MIN:
3353 aPBPos.iPosValue.min_value = aTimeMS / 60000;
3354 break;
3355
3356 case PVPPBPOSUNIT_HOUR:
3357 aPBPos.iPosValue.hour_value = aTimeMS / 3600000;
3358 break;
3359
3360 case PVPPBPOSUNIT_SMPTE:
3361 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertFromMillisec() SMPTE units not supported yet"));
3362 return PVMFErrArgument;
3363
3364 case PVPPBPOSUNIT_PERCENT:
3365 {
3366 if (iSourceDurationAvailable == false)
3367 {
3368 // Duration info not available from source node so can't convert
3369 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Duration not available so can't convert"));
3370 return PVMFErrArgument;
3371 }
3372
3373 if (iSourceDurationInMS == 0)
3374 {
3375 // Duration is 0 so can't convert
3376 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Duration value is 0 so can't convert"));
3377 return PVMFErrArgument;
3378 }
3379
3380 if (aTimeMS >= iSourceDurationInMS)
3381 {
3382 // Put a ceiling of 100%
3383 aPBPos.iPosValue.percent_value = 100;
3384 }
3385 else
3386 {
3387 // Calculate percentage of playback, avoiding overflow
3388 if (iSourceDurationInMS >= PVP_MIN_PLAYSTATUS_PERCENT_OVERFLOW_THRESHOLD)
3389 {
3390 aPBPos.iPosValue.percent_value = aTimeMS / (iSourceDurationInMS / 100);
3391 }
3392 else
3393 {
3394 aPBPos.iPosValue.percent_value = (aTimeMS * 100) / iSourceDurationInMS;
3395 }
3396 }
3397 }
3398 break;
3399
3400 case PVPPBPOSUNIT_SAMPLENUMBER:
3401 {
3402 if (iSourceNodeTrackLevelInfoIF == NULL)
3403 {
3404 // The source node doesn't have the query IF to convert time to sample number
3405 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Time to sample numberconversion not available"));
3406 return PVMFErrArgument;
3407 }
3408
3409 // Determine which track to use for conversion.
3410 // Give preference to video track, then text, and finally audio
3411 PVMFTrackInfo* track = NULL;
3412 int32 datapathIndex = -1;
3413
3414 // Search from the datapath list.
3415 // 1) Try for video track
3416 bool retVal = FindDatapathForTrackUsingMimeString(true, false, false, datapathIndex);
3417 if (retVal == false)
3418 {
3419 // Video track not available, look for text track
3420 retVal = FindDatapathForTrackUsingMimeString(false, false, true, datapathIndex);
3421 if (retVal == false)
3422 {
3423 // Text track also not avaliable, look for audio track
3424 retVal = FindDatapathForTrackUsingMimeString(false, true, false, datapathIndex);
3425 if (retVal == false)
3426 {
3427 // Track is not available to do the conversion
3428 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertToMillisec() Track not selected for conversion"));
3429 return PVMFErrArgument;
3430 }
3431 }
3432 }
3433
3434 // Track avalaible.
3435 track = iDatapathList[datapathIndex].iTrackInfo;
3436
3437 // Convert the time to sample number
3438 PVMFTimestamp ts = aTimeMS;
3439 uint32 samplenum = 0;
3440 if (iSourceNodeTrackLevelInfoIF->GetSampleNumberForTimestamp(*track, ts, samplenum) != PVMFSuccess)
3441 {
3442 // Conversion failed
3443 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Sample number to time conversion failed"));
3444 return PVMFErrArgument;
3445 }
3446
3447 aPBPos.iPosValue.samplenum_value = samplenum;
3448 }
3449 break;
3450
3451 case PVPPBPOSUNIT_DATAPOSITION:
3452 {
3453 if (iSourceNodeTrackLevelInfoIF == NULL)
3454 {
3455 // The source node doesn't have the ext IF to convert time to data position
3456 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Time to data position conversion not available in source node"));
3457 return PVMFErrArgument;
3458 }
3459
3460 // Query each active track for its data position
3461 // Return the max data position
3462 PVMFTimestamp ts = aTimeMS;
3463 uint32 maxdatapos = 0;
3464 bool maxdataposvalid = false;
3465
3466 // Go through each active track
3467 for (uint32 i = 0; i < iDatapathList.size(); ++i)
3468 {
3469 if (iDatapathList[i].iDatapath)
3470 {
3471 uint32 curdatapos = 0;
3472 // Convert the time to data position
3473 if (iSourceNodeTrackLevelInfoIF->GetDataPositionForTimestamp(*(iDatapathList[i].iTrackInfo), ts, curdatapos) != PVMFSuccess)
3474 {
3475 // Conversion failed
3476 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Time to data position conversion failed"));
3477 }
3478 else
3479 {
3480 // Save the data position if it is greater than
3481 // any position encountered so far.
3482 maxdataposvalid = true;
3483 if (curdatapos > maxdatapos)
3484 {
3485 maxdatapos = curdatapos;
3486 }
3487 }
3488 }
3489 }
3490
3491 if (maxdataposvalid == false)
3492 {
3493 // Conversion failed for all active tracks
3494 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::ConvertFromMillisec() Track not selected for conversion"));
3495 return PVMFErrArgument;
3496 }
3497 // Save the data position to return
3498 aPBPos.iPosValue.datapos_value = maxdatapos;
3499 }
3500 break;;
3501
3502 default:
3503 // Don't support the other units for now
3504 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::ConvertFromMillisec() Unsupported position units"));
3505 return PVMFErrArgument;
3506 }
3507
3508 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::ConvertFromMillisec() Out"));
3509 return PVMFSuccess;
3510 }
3511
3512
EngineCommandCompleted(PVCommandId aId,OsclAny * aContext,PVMFStatus aStatus,PVInterface * aExtInterface,OsclAny * aEventData,int32 aEventDataSize)3513 void PVPlayerEngine::EngineCommandCompleted(PVCommandId aId, OsclAny* aContext, PVMFStatus aStatus, PVInterface* aExtInterface, OsclAny* aEventData, int32 aEventDataSize)
3514 {
3515 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::EngineCommandCompleted() In CmdId %d, Status %d", aId, aStatus));
3516
3517 // Update the current command vector
3518
3519 // Assert if the current cmd is not saved or the cmd ID does not match
3520 OSCL_ASSERT(iCurrentCmd.size() == 1);
3521 OSCL_ASSERT(iCurrentCmd[0].GetCmdId() == aId);
3522
3523 // Empty out the current cmd vector and set active if there are other pending commands
3524 PVPlayerEngineCommand completedcmd(iCurrentCmd[0]);
3525 iCurrentCmd.erase(iCurrentCmd.begin());
3526 if (!iPendingCmds.empty())
3527 {
3528 RunIfNotReady();
3529 }
3530
3531 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
3532 (0, "PVPlayerEngine::EngineCommandCompleted() Type=%d ID=%d APIcmd=%d Tick=%d",
3533 completedcmd.GetCmdType(), completedcmd.GetCmdId(), completedcmd.IsAPICommand(), OsclTickCount::TickCount()));
3534
3535 // Send informational event or send other callback if needed
3536 switch (completedcmd.GetCmdType())
3537 {
3538 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP:
3539 SendEndOfClipInfoEvent(aStatus, aExtInterface);
3540 break;
3541
3542 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED:
3543 SendEndTimeReachedInfoEvent(aStatus, aExtInterface);
3544 break;
3545
3546 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW:
3547 SendSourceUnderflowInfoEvent(aStatus, aExtInterface);
3548 break;
3549
3550 case PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY:
3551 SendSourceDataReadyInfoEvent(aStatus, aExtInterface);
3552 break;
3553
3554 case PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS:
3555 // Send callback to the specified observer
3556 if (iCfgCapCmdObserver)
3557 {
3558 iCfgCapCmdObserver->SignalEvent(aId);
3559 }
3560 break;
3561
3562 default:
3563 // None to be sent
3564 break;
3565 }
3566
3567 // Send the command completed event
3568 if (iCmdStatusObserver)
3569 {
3570 if (aId != -1 && completedcmd.IsAPICommand())
3571 {
3572 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::EngineCommandCompleted() Notifying engine command as completed. CmdId %d Status %d", aId, aStatus));
3573 PVCmdResponse cmdcompleted(aId, aContext, aStatus, aExtInterface, aEventData, aEventDataSize);
3574 iCmdStatusObserver->CommandCompleted(cmdcompleted);
3575 }
3576 else
3577 {
3578 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::EngineCommandCompleted() aId is -1 or not an API command. CmdType %d", completedcmd.GetCmdType()));
3579 }
3580 }
3581 else
3582 {
3583 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::EngineCommandCompleted() iCmdStatusObserver is NULL"));
3584 }
3585 }
3586
3587
SendInformationalEvent(PVMFEventType aEventType,PVInterface * aExtInterface,OsclAny * aEventData,uint8 * aLocalBuffer,uint32 aLocalBufferSize)3588 void PVPlayerEngine::SendInformationalEvent(PVMFEventType aEventType, PVInterface* aExtInterface, OsclAny* aEventData, uint8* aLocalBuffer, uint32 aLocalBufferSize)
3589 {
3590 // Send the info event if observer has been specified
3591 if (iInfoEventObserver)
3592 {
3593 PVAsyncInformationalEvent infoevent((PVEventType)aEventType, NULL, aExtInterface, (PVExclusivePtr)aEventData, aLocalBuffer, aLocalBufferSize);
3594 iInfoEventObserver->HandleInformationalEvent(infoevent);
3595 }
3596 else
3597 {
3598 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SendInformationalEvent() iInfoEventObserver is NULL"));
3599 }
3600 }
3601
3602
SendErrorEvent(PVMFEventType aEventType,PVInterface * aExtInterface,OsclAny * aEventData,uint8 * aLocalBuffer,uint32 aLocalBufferSize)3603 void PVPlayerEngine::SendErrorEvent(PVMFEventType aEventType, PVInterface* aExtInterface, OsclAny* aEventData, uint8* aLocalBuffer, uint32 aLocalBufferSize)
3604 {
3605 // Send the error event if observer has been specified
3606 if (iErrorEventObserver)
3607 {
3608 PVAsyncErrorEvent errorevent((PVEventType)aEventType, NULL, aExtInterface, (PVExclusivePtr)aEventData, aLocalBuffer, aLocalBufferSize);
3609 iErrorEventObserver->HandleErrorEvent(errorevent);
3610 }
3611 else
3612 {
3613 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SendErrorEvent() iErrorEventObserver is NULL"));
3614 }
3615 }
3616
3617
DoCancelCommand(PVPlayerEngineCommand & aCmd)3618 void PVPlayerEngine::DoCancelCommand(PVPlayerEngineCommand& aCmd)
3619 {
3620 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommand() In"));
3621
3622 // Boolean to check if the command is cancelled or not.
3623 bool commandCancelled = false;
3624
3625 // cmd to cancel either has been completed or is in pending queue.
3626 // Create a temporary queue for pending commands and current command if any.
3627 OsclPriorityQueue<PVPlayerEngineCommand, OsclMemAllocator, Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator>, PVPlayerEngineCommandCompareLess> iTempPendingCmds;
3628 Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> iTempCurrentCmd;
3629 // Copy the pending commands to the new queue
3630 iTempPendingCmds = iPendingCmds;
3631 while (!iTempPendingCmds.empty())
3632 {
3633 // Get the queue from the top
3634 PVPlayerEngineCommand cmd(iTempPendingCmds.top());
3635 // Check if it needs to be cancelled
3636 if (aCmd.GetParam(0).int32_value == cmd.GetCmdId())
3637 {
3638 // Found command to be cancelled in the Pending Queue, set the
3639 // commandCancelled boolean to true.
3640 commandCancelled = true;
3641
3642 // Remove it from the pending commands queue
3643 iPendingCmds.remove(cmd);
3644 // Save it temporary as "current command" and then cancel it. If CurrentCmd has some
3645 // command, first move it to TempCurrentCmd queue.
3646 if (!iCurrentCmd.empty())
3647 {
3648 iTempCurrentCmd.push_front(iCurrentCmd[0]);
3649 iCurrentCmd.erase(iCurrentCmd.begin());
3650 }
3651
3652 iCurrentCmd.push_front(cmd);
3653 EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), PVMFErrCancelled);
3654
3655 // send command complete for CancelCommand also.
3656 iCurrentCmd.push_front(aCmd);
3657 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
3658
3659 // If TempCurrentCmd queue is holding up any command, move it back to CurrentCmd queue.
3660 if (!iTempCurrentCmd.empty())
3661 {
3662 iCurrentCmd.push_front(iTempCurrentCmd[0]);
3663 iTempCurrentCmd.erase(iTempCurrentCmd.begin());
3664 }
3665 }
3666 // Pop each cmd from the temporary queue
3667 iTempPendingCmds.pop();
3668 }
3669
3670 if (!commandCancelled)
3671 {
3672 // There was no command cancelled, user might have given a wrong Argument
3673 // Fail the command with PVMFErrArgument
3674 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelCommand() Wrong Argument, No comand cancelled"));
3675 if (!iCurrentCmd.empty())
3676 {
3677 PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
3678 iCurrentCmd.erase(iCurrentCmd.begin());
3679 iCurrentCmd.push_front(aCmd);
3680 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrArgument);
3681 iCurrentCmd.push_front(currentcmd);
3682 }
3683 else
3684 {
3685 // Current Command is empty, just push CancelCommand and do Command Complete.
3686 iCurrentCmd.push_front(aCmd);
3687 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrArgument);
3688 }
3689 }
3690 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommand() Out"));
3691 }
3692
3693
DoCancelAllCommands(PVPlayerEngineCommand & aCmd)3694 void PVPlayerEngine::DoCancelAllCommands(PVPlayerEngineCommand& aCmd)
3695 {
3696 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAllCommands() In"));
3697
3698
3699 // Engine cannot be processing another cancel command
3700 OSCL_ASSERT(iCmdToCancel.empty() == true);
3701
3702 // While AcquireLicense and CancelAcquireLicense is processing, CancelAllCommands is prohibited.
3703 if (!iCmdToDlaCancel.empty() ||
3704 (!iCurrentCmd.empty() &&
3705 (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE ||
3706 iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR ||
3707 iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR)))
3708 {
3709 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAllCommands() Error due to processing AcquireLicense or CancelAcquireLicense,CmdType=%d", iCurrentCmd[0].GetCmdType()));
3710 PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
3711 iCurrentCmd.erase(iCurrentCmd.begin());
3712 iCurrentCmd.push_front(aCmd);
3713 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrArgument);
3714 iCurrentCmd.push_front(currentcmd);
3715 return;
3716 }
3717 // set engine state to Resetting, as cancel command completion will take Engine to Idle state, after internal reset.
3718 SetEngineState(PVP_ENGINE_STATE_RESETTING);
3719 iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
3720 // Stop the playback clock
3721 iPlaybackClock.Stop();
3722 // Cancel the current command first
3723 if (iCurrentCmd.size() == 1)
3724 {
3725 // First save the current command being processed
3726 iCmdToCancel.push_front(iCurrentCmd[0]);
3727 // Cancel it
3728 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFErrCancelled);
3729 }
3730
3731 // Cancel all the pending commands
3732
3733 // Create a temporary queue for pending commands
3734 OsclPriorityQueue<PVPlayerEngineCommand, OsclMemAllocator, Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator>, PVPlayerEngineCommandCompareLess> iTempPendingCmds;
3735 // Copy the pending commands to the new queue
3736 iTempPendingCmds = iPendingCmds;
3737 while (!iTempPendingCmds.empty())
3738 {
3739 // Get the queue from the top
3740 PVPlayerEngineCommand cmd(iTempPendingCmds.top());
3741 // Check if it needs to be cancelled
3742 if ((aCmd.GetCmdId() > cmd.GetCmdId()) && !((aCmd.GetCmdId() - cmd.GetCmdId()) > 0x7FFFFFFF))
3743 {
3744 // Remove it from the pending commands queue
3745 iPendingCmds.remove(cmd);
3746 // Save it temporary as "current command" and then cancel it
3747 iCurrentCmd.push_front(cmd);
3748 EngineCommandCompleted(cmd.GetCmdId(), cmd.GetContext(), PVMFErrCancelled);
3749 }
3750 // Pop each cmd from the temporary queue
3751 iTempPendingCmds.pop();
3752 }
3753
3754
3755 // Make the CancelAll() command the current command
3756 iCurrentCmd.push_front(aCmd);
3757
3758 // Check if there was an ongoing command that needs to be properly cancelled
3759 if (!iCmdToCancel.empty())
3760 {
3761
3762 // Properly cancel a command being currently processed
3763 DoCancelCommandBeingProcessed();
3764 }
3765 else
3766 {
3767 // Nothing to cancel, move on to resetting Source Nodes and Datapaths
3768 if (iSourceNode)
3769 {
3770 int32 leavecode = 0;
3771 // call reset on source node if not in created state
3772 if (iSourceNode->GetState() != EPVMFNodeCreated)
3773 {
3774 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
3775 (0, "PVPlayerEngine::DoCancelAllCommands() Issue reset on Source Node"));
3776 // error handling code set engine state to resetting
3777 SetEngineState(PVP_ENGINE_STATE_RESETTING);
3778
3779 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
3780
3781 PVMFCommandId cmdid = -1;
3782 leavecode = 0;
3783 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
3784 OSCL_FIRST_CATCH_ANY(leavecode,
3785
3786 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
3787 (0, "PVPlayerEngine::DoCancelAllCommands() Reset on iSourceNode did a leave!"));
3788 FreeEngineContext(context);
3789 OSCL_ASSERT(false););
3790
3791 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAllCommands() Out"));
3792 return;
3793 }
3794 }
3795
3796 if (iDataSource)
3797 {
3798 RemoveDataSourceSync(*iDataSource);
3799 }
3800 SetEngineState(PVP_ENGINE_STATE_IDLE);
3801 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
3802 }
3803
3804 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAllCommands() Out"));
3805 }
3806
3807
DoCancelCommandBeingProcessed(void)3808 void PVPlayerEngine::DoCancelCommandBeingProcessed(void)
3809 {
3810 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() In"));
3811
3812 // There should be a command to cancel
3813 OSCL_ASSERT(iCmdToCancel.empty() == false);
3814
3815 // If cmd to cancel is GetMetadataKeys() or GetMetadataValues(), first release the memory for
3816 // nodes which have already completed the call and then issue cancel on other nodes.
3817 switch (iCmdToCancel[0].GetCmdType())
3818 {
3819 case PVP_ENGINE_COMMAND_GET_METADATA_KEY:
3820 {
3821 // Release the memory allocated for the metadata keys
3822 while (iMetadataKeyReleaseList.empty() == false)
3823 {
3824 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataKeyReleaseList[0].iMetadataIFListIndex].iInterface;
3825 OSCL_ASSERT(mdif != NULL);
3826 mdif->ReleaseNodeMetadataKeys(*(iGetMetadataKeysParam.iKeyList), iMetadataKeyReleaseList[0].iStartIndex, iMetadataKeyReleaseList[0].iEndIndex);
3827 iMetadataKeyReleaseList.erase(iMetadataKeyReleaseList.begin());
3828 }
3829 // no need to break from the current switch, as we need to issue Cancel on nodes. Continue.
3830 }
3831 case PVP_ENGINE_COMMAND_GET_METADATA_VALUE:
3832 {
3833 // Release the memory allocated for the metadata values
3834 while (iMetadataValueReleaseList.empty() == false)
3835 {
3836 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
3837 OSCL_ASSERT(mdif != NULL);
3838 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
3839 iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
3840 }
3841
3842 iReleaseMetadataValuesPending = false;
3843 // no need to break from the current switch, as we need to issue Cancel on nodes. Continue.
3844 }
3845 case PVP_ENGINE_COMMAND_ADD_DATA_SOURCE:
3846 case PVP_ENGINE_COMMAND_INIT:
3847 case PVP_ENGINE_COMMAND_PREPARE:
3848 case PVP_ENGINE_COMMAND_PAUSE:
3849 case PVP_ENGINE_COMMAND_RESUME:
3850 case PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE:
3851 case PVP_ENGINE_COMMAND_SET_PLAYBACK_RATE:
3852 case PVP_ENGINE_COMMAND_CANCEL_COMMAND:
3853 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDTIME_REACHED:
3854 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP:
3855 case PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW:
3856 case PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY:
3857 case PVP_ENGINE_COMMAND_STOP:
3858 {
3859 // go ahead and issue cancel on nodes and datapath if needed.
3860 if (!iCurrentContextList.empty())
3861 {
3862 // Since there is a pending node or datapath, cancel it
3863 PVMFStatus status = DoCancelPendingNodeDatapathCommand();
3864 if (status == PVMFPending)
3865 {
3866 // There are some commands which need to be cancelled so wait for cancel complete
3867 // once cancels complete, we would start the reset sequence from either
3868 // NodeCommandComplete, HandlePlayerDataPathEvent, RecognizeComplete
3869 break;
3870 }
3871 }
3872
3873 // No pending command so reset the nodes now
3874 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() No command to cancel, now reset all nodes"));
3875
3876 // reset the source node
3877 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
3878
3879 PVMFCommandId cmdid = -1;
3880 int32 leavecode = 0;
3881 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
3882 OSCL_FIRST_CATCH_ANY(leavecode,
3883
3884 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() Reset on iSourceNode did a leave!"));
3885 FreeEngineContext(context);
3886 OSCL_ASSERT(false);
3887 return);
3888
3889 SetEngineState(PVP_ENGINE_STATE_RESETTING);
3890 break;
3891 }
3892
3893 case PVP_ENGINE_COMMAND_QUERY_UUID:
3894 case PVP_ENGINE_COMMAND_QUERY_INTERFACE:
3895 case PVP_ENGINE_COMMAND_GET_PLAYBACK_RANGE:
3896 case PVP_ENGINE_COMMAND_GET_PLAYBACK_RATE:
3897 case PVP_ENGINE_COMMAND_GET_PLAYBACK_MINMAX_RATE:
3898 case PVP_ENGINE_COMMAND_GET_SDK_INFO:
3899 case PVP_ENGINE_COMMAND_GET_SDK_MODULE_INFO:
3900 case PVP_ENGINE_COMMAND_SET_LOG_APPENDER:
3901 case PVP_ENGINE_COMMAND_REMOVE_LOG_APPENDER:
3902 case PVP_ENGINE_COMMAND_SET_LOG_LEVEL:
3903 case PVP_ENGINE_COMMAND_GET_LOG_LEVEL:
3904 case PVP_ENGINE_COMMAND_CANCEL_ALL_COMMANDS:
3905 case PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE:
3906 case PVP_ENGINE_COMMAND_ADD_DATA_SINK:
3907 case PVP_ENGINE_COMMAND_GET_CURRENT_POSITION:
3908 case PVP_ENGINE_COMMAND_START:
3909 case PVP_ENGINE_COMMAND_REMOVE_DATA_SINK:
3910 case PVP_ENGINE_COMMAND_REMOVE_DATA_SOURCE:
3911 default:
3912 // These commands should complete in one AO scheduling so there should be no need to cancel.
3913 // CancelAll() is done so complete it
3914 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFSuccess);
3915 break;
3916 }
3917
3918 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelCommandBeingProcessed() Out"));
3919 }
3920
3921
DoCancelPendingNodeDatapathCommand()3922 PVMFStatus PVPlayerEngine::DoCancelPendingNodeDatapathCommand()
3923 {
3924 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() In"));
3925
3926 OSCL_ASSERT(iCurrentContextList.empty() == false);
3927
3928 // Determine where the pending commands were issued to and then cancel them
3929 int32 leavecode = 0;
3930 iNumberCancelCmdPending = 0;
3931 for (uint32 i = 0; i < iCurrentContextList.size(); ++i)
3932 {
3933 if (iCurrentContextList[i]->iNode)
3934 {
3935 if (iCurrentContextList[i]->iNode == iSourceNode)
3936 {
3937 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on source node"));
3938 leavecode = IssueNodeCancelCommand(iCurrentContextList[i], iSourceNodeSessionId, (OsclAny*) & iNumberCancelCmdPending);
3939 if (leavecode == 0)
3940 {
3941 ++iNumberCancelCmdPending;
3942 }
3943 else
3944 {
3945 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
3946 (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on source node did a leave"));
3947 FreeEngineContext(iCurrentContextList[i]);
3948 }
3949 }
3950 else if (iCurrentContextList[i]->iEngineDatapath != NULL)
3951 {
3952 if (iCurrentContextList[i]->iNode == iCurrentContextList[i]->iEngineDatapath->iSinkNode)
3953 {
3954 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on sink node"));
3955 leavecode = IssueNodeCancelCommand(iCurrentContextList[i], iCurrentContextList[i]->iEngineDatapath->iSinkNodeSessionId, (OsclAny*) & iNumberCancelCmdPending);
3956 if (leavecode == 0)
3957 {
3958 ++iNumberCancelCmdPending;
3959 }
3960 else
3961 {
3962 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
3963 (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on sink node did a leave"));
3964 FreeEngineContext(iCurrentContextList[i]);
3965 }
3966 }
3967 else if (iCurrentContextList[i]->iNode == iCurrentContextList[i]->iEngineDatapath->iDecNode)
3968 {
3969 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on dec node"));
3970 leavecode = IssueNodeCancelCommand(iCurrentContextList[i], iCurrentContextList[i]->iEngineDatapath->iDecNodeSessionId, (OsclAny*) & iNumberCancelCmdPending);
3971 if (leavecode == 0)
3972 {
3973 ++iNumberCancelCmdPending;
3974 }
3975 else
3976 {
3977 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
3978 (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on dec node did a leave"));
3979 FreeEngineContext(iCurrentContextList[i]);
3980 }
3981 }
3982 else
3983 {
3984 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Unknown node type. Asserting"));
3985 OSCL_ASSERT(false);
3986 }
3987 }
3988 else
3989 {
3990 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Unknown node. Asserting"));
3991 OSCL_ASSERT(false);
3992 }
3993 }
3994 else if (iCurrentContextList[i]->iDatapath != NULL)
3995 {
3996 if (iCurrentContextList[i]->iEngineDatapath != NULL)
3997 {
3998 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on datapath"));
3999 leavecode = IssueDatapathCancelCommand(iCurrentContextList[i], (OsclAny*) & iNumberCancelCmdPending);
4000 if (leavecode == 0)
4001 {
4002 ++iNumberCancelCmdPending;
4003 }
4004 }
4005 else
4006 {
4007 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Unknown datapath. Asserting"));
4008 OSCL_ASSERT(false);
4009 }
4010 }
4011 else if (iCurrentContextList[i]->iCmdType == PVP_CMD_QUERYSOURCEFORMATTYPE)
4012 {
4013 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Calling CancelAllCommands() on recognizer"));
4014 leavecode = IssueRecognizerRegistryCancel((OsclAny*) & iNumberCancelCmdPending);
4015 if (leavecode == 0)
4016 {
4017 ++iNumberCancelCmdPending;
4018 }
4019 else
4020 {
4021 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
4022 (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on recognizer node did a leave"));
4023 FreeEngineContext(iCurrentContextList[i]);
4024 }
4025 }
4026 else
4027 {
4028 // Either a node or datapath should be pending
4029 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() No pending node or datapath. Asserting"));
4030 OSCL_ASSERT(false);
4031 }
4032 }
4033
4034 if (iNumberCancelCmdPending == 0)
4035 {
4036 // Cancel on the node / datapath failed so go to next step
4037 // Note that we do not care about not being able to queue cancel since
4038 // we are going to reset the components anyway
4039 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() CancelAllCommands() on the node did a leave"));
4040 RemoveDatapathContextFromList(); // remove left-over datapath contexts
4041 return PVMFSuccess;
4042 }
4043 else
4044 {
4045 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() %d CancelAllCommands are pending", iNumberCancelCmdPending));
4046 }
4047
4048 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelPendingNodeDatapathCommand() Out"));
4049 return PVMFPending;
4050 }
4051
DoGetSDKInfo(PVPlayerEngineCommand & aCmd)4052 PVMFStatus PVPlayerEngine::DoGetSDKInfo(PVPlayerEngineCommand& aCmd)
4053 {
4054 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetSDKInfo() In"));
4055
4056 PVSDKInfo* sdkinfo = (PVSDKInfo*)(aCmd.GetParam(0).pOsclAny_value);
4057 if (sdkinfo == NULL)
4058 {
4059 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetSDKInfo() Passed in parameter invalid."));
4060 return PVMFErrArgument;
4061 }
4062
4063 // Set the SDK info to the ones defined in the header file pv_player_sdkinfo.h generated at build time
4064 sdkinfo->iLabel = PVPLAYER_ENGINE_SDKINFO_LABEL;
4065 sdkinfo->iDate = PVPLAYER_ENGINE_SDKINFO_DATE;
4066
4067 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(), iCurrentCmd[0].GetContext(), PVMFSuccess);
4068
4069 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetSDKInfo() Out"));
4070 return PVMFSuccess;
4071 }
4072
4073
DoSetLogAppender(PVPlayerEngineCommand & aCmd)4074 PVMFStatus PVPlayerEngine::DoSetLogAppender(PVPlayerEngineCommand& aCmd)
4075 {
4076 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogAppender() In"));
4077
4078 char* tag = (char*)(aCmd.GetParam(0).pChar_value);
4079 OsclSharedPtr<PVLoggerAppender>* appender = (OsclSharedPtr<PVLoggerAppender>*)(aCmd.GetParam(1).pOsclAny_value);
4080
4081 if (tag == NULL || appender == NULL)
4082 {
4083 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogAppender() Passed in parameter invalid."));
4084 return PVMFErrArgument;
4085 }
4086
4087 // Get the logger node based on the specified tag
4088 PVLogger *rootnode = PVLogger::GetLoggerObject(tag);
4089 if (rootnode == NULL)
4090 {
4091 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogAppender() Node specified by tag is invalid"));
4092 return PVMFErrBadHandle;
4093 }
4094
4095 // Add the specified appender to this node
4096 rootnode->AddAppender(*appender);
4097
4098 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4099
4100
4101 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogAppender() Out"));
4102 return PVMFSuccess;
4103 }
4104
4105
DoRemoveLogAppender(PVPlayerEngineCommand & aCmd)4106 PVMFStatus PVPlayerEngine::DoRemoveLogAppender(PVPlayerEngineCommand& aCmd)
4107 {
4108 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveLogAppender() In"));
4109
4110 char* tag = (char*)(aCmd.GetParam(0).pChar_value);
4111 OsclSharedPtr<PVLoggerAppender>* appender = (OsclSharedPtr<PVLoggerAppender>*)(aCmd.GetParam(1).pOsclAny_value);
4112
4113 if (tag == NULL || appender == NULL)
4114 {
4115 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveLogAppender() Passed in parameter invalid."));
4116 return PVMFErrArgument;
4117 }
4118
4119 // Get the logger node based on the specified tag
4120 PVLogger *lognode = PVLogger::GetLoggerObject(tag);
4121 if (lognode == NULL)
4122 {
4123 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveLogAppender() Node specified by tag is invalid"));
4124 return PVMFErrBadHandle;
4125 }
4126
4127 // Remove the specified appender to this node
4128 lognode->RemoveAppender(*appender);
4129
4130 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4131
4132
4133 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveLogAppender() Out"));
4134 return PVMFSuccess;
4135 }
4136
4137
DoSetLogLevel(PVPlayerEngineCommand & aCmd)4138 PVMFStatus PVPlayerEngine::DoSetLogLevel(PVPlayerEngineCommand& aCmd)
4139 {
4140 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogLevel() In"));
4141
4142 char* tag = (char*)(aCmd.GetParam(0).pChar_value);
4143 int32 level = aCmd.GetParam(1).int32_value;
4144 bool subtree = aCmd.GetParam(2).bool_value;
4145
4146 if (tag == NULL)
4147 {
4148 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogLevel() Passed in parameter invalid."));
4149 return PVMFErrArgument;
4150 }
4151
4152 // Get the logger node based on the specified tag
4153 PVLogger *lognode = PVLogger::GetLoggerObject(tag);
4154 if (lognode == NULL)
4155 {
4156 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetLogLevel() Node specified by tag is invalid"));
4157 return PVMFErrBadHandle;
4158 }
4159
4160 // Set the log level
4161 if (subtree)
4162 {
4163 lognode->SetLogLevelAndPropagate(level);
4164 }
4165 else
4166 {
4167 lognode->SetLogLevel(level);
4168 }
4169
4170 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4171
4172
4173 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetLogLevel() Out"));
4174 return PVMFSuccess;
4175 }
4176
4177
DoGetLogLevel(PVPlayerEngineCommand & aCmd)4178 PVMFStatus PVPlayerEngine::DoGetLogLevel(PVPlayerEngineCommand& aCmd)
4179 {
4180 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLogLevel() In"));
4181
4182 char* tag = (char*)(aCmd.GetParam(0).pChar_value);
4183 PVLogLevelInfo* levelinfo = (PVLogLevelInfo*)(aCmd.GetParam(1).pOsclAny_value);
4184
4185 if (tag == NULL || levelinfo == NULL)
4186 {
4187 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetLogLevel() Passed in parameter invalid."));
4188 return PVMFErrArgument;
4189 }
4190
4191 // Get the logger node based on the specified tag
4192 PVLogger *lognode = PVLogger::GetLoggerObject(tag);
4193 if (lognode == NULL)
4194 {
4195 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetLogLevel() Node specified by tag is invalid"));
4196 return PVMFErrBadHandle;
4197 }
4198
4199 // Get the log level info
4200 *levelinfo = lognode->GetLogLevel();
4201
4202 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4203
4204 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetLogLevel() Out"));
4205 return PVMFSuccess;
4206 }
4207
4208
DoQueryUUID(PVPlayerEngineCommand & aCmd)4209 PVMFStatus PVPlayerEngine::DoQueryUUID(PVPlayerEngineCommand& aCmd)
4210 {
4211 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryUUID() In"));
4212
4213 PvmfMimeString* mimetype;
4214 Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
4215 bool exactmatch;
4216
4217 mimetype = (PvmfMimeString*)(aCmd.GetParam(0).pOsclAny_value);
4218 uuidvec = (Oscl_Vector<PVUuid, OsclMemAllocator>*)(aCmd.GetParam(1).pOsclAny_value);
4219 exactmatch = aCmd.GetParam(2).bool_value;
4220
4221 if (mimetype == NULL || uuidvec == NULL)
4222 {
4223 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoQueryUUID() Passed in parameter invalid."));
4224 return PVMFErrArgument;
4225 }
4226
4227 int32 leavecode = 0;
4228
4229 // For now just return all available extension interface UUID
4230 OSCL_TRY(leavecode,
4231 // Capability and config interface
4232 uuidvec->push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID);
4233 // License acquisition interface
4234 uuidvec->push_back(PVPlayerLicenseAcquisitionInterfaceUuid);
4235 // Track level info interface from source node
4236 if (iSourceNodeTrackLevelInfoIF)
4237 {
4238 uuidvec->push_back(PVMF_TRACK_LEVEL_INFO_INTERFACE_UUID);
4239 }
4240 );
4241 OSCL_FIRST_CATCH_ANY(leavecode,
4242 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoQueryUUID() Leaved"));
4243 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFErrNoMemory);
4244 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryUUID() Out"));
4245 return PVMFSuccess;);
4246
4247 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4248
4249 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryUUID() Out"));
4250 return PVMFSuccess;
4251 }
4252
4253
DoQueryInterface(PVPlayerEngineCommand & aCmd)4254 PVMFStatus PVPlayerEngine::DoQueryInterface(PVPlayerEngineCommand& aCmd)
4255 {
4256 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryInterface() In"));
4257
4258 PVInterface** ifptr = (PVInterface**)(aCmd.GetParam(0).pOsclAny_value);
4259 PVUuid uuid = aCmd.GetUuid();
4260 if (ifptr == NULL)
4261 {
4262 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoQueryInterface() Passed in parameter invalid."));
4263 return PVMFErrArgument;
4264 }
4265
4266 PVMFStatus cmdstatus = PVMFSuccess;
4267 if (queryInterface(uuid, *ifptr) == false)
4268 {
4269 cmdstatus = PVMFErrNotSupported;
4270 }
4271 else
4272 {
4273 (*ifptr)->addRef();
4274 }
4275
4276 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), cmdstatus);
4277
4278 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQueryInterface() Out"));
4279 return PVMFSuccess;
4280 }
4281
4282
DoGetPVPlayerState(PVPlayerEngineCommand & aCmd,bool aSyncCmd)4283 PVMFStatus PVPlayerEngine::DoGetPVPlayerState(PVPlayerEngineCommand& aCmd, bool aSyncCmd)
4284 {
4285 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPVPlayerState() In"));
4286
4287 PVPlayerState* state = (PVPlayerState*)(aCmd.GetParam(0).pOsclAny_value);
4288 if (state == NULL)
4289 {
4290 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPVPlayerState() Passed in parameter invalid."));
4291 return PVMFErrArgument;
4292 }
4293
4294 // Get player state using internal function
4295 *state = GetPVPlayerState();
4296
4297 if (!aSyncCmd)
4298 {
4299 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4300 }
4301
4302 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPVPlayerState() Out"));
4303 return PVMFSuccess;
4304 }
4305
4306
DoAddDataSource(PVPlayerEngineCommand & aCmd)4307 PVMFStatus PVPlayerEngine::DoAddDataSource(PVPlayerEngineCommand& aCmd)
4308 {
4309 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
4310 (0, "PVPlayerEngine::DoAddDataSource() Tick=%d", OsclTickCount::TickCount()));
4311
4312 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSource() In"));
4313
4314 if (GetPVPlayerState() != PVP_STATE_IDLE)
4315 {
4316 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() Wrong engine state"));
4317 return PVMFErrInvalidState;
4318 }
4319
4320 if (aCmd.GetParam(0).pOsclAny_value == NULL)
4321 {
4322 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() Passed in parameter invalid."));
4323 return PVMFErrArgument;
4324 }
4325
4326 // Save the data source
4327 iDataSource = (PVPlayerDataSource*)(aCmd.GetParam(0).pOsclAny_value);
4328
4329 // (mg) For rollover reset to first available alternate
4330 iAlternateSrcFormatIndex = 0;
4331 iDataReadySent = false;
4332
4333 // Check the source format and do a recognize if unknown
4334 PVMFStatus retval = PVMFSuccess;
4335 iSourceFormatType = iDataSource->GetDataSourceFormatType();
4336
4337 if (iSourceFormatType == PVMF_MIME_FORMAT_UNKNOWN)
4338 {
4339 retval = DoQuerySourceFormatType(aCmd.GetCmdId(), aCmd.GetContext());
4340 }
4341 else
4342 {
4343 if (iSourceFormatType == PVMF_MIME_DATA_SOURCE_UNKNOWN_URL)
4344 {
4345 retval = SetupDataSourceForUnknownURLAccess();
4346 if (retval != PVMFSuccess)
4347 {
4348 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSource() - SetupDataSourceForUnknownURLAccess Failed"));
4349 return retval;
4350 }
4351 }
4352
4353 // Start the source node creation and setup sequence
4354 retval = DoSetupSourceNode(aCmd.GetCmdId(), aCmd.GetContext());
4355
4356 if (retval != PVMFSuccess)
4357 {
4358 bool ehPending = CheckForPendingErrorHandlingCmd();
4359 if (ehPending)
4360 {
4361 // there should be no error handling queued.
4362 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() Already EH pending, should never happen"));
4363 return PVMFPending;
4364 }
4365 // Queue up Error Handling
4366 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSource() DoSetupSourceNode failed, Add EH command"));
4367 iCommandCompleteStatusInErrorHandling = retval;
4368 iCommandCompleteErrMsgInErrorHandling = NULL;
4369 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
4370 return PVMFPending;
4371 }
4372 }
4373
4374 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSource() Out"));
4375 return retval;
4376
4377 }
4378
4379
DoQuerySourceFormatType(PVCommandId aCmdId,OsclAny * aCmdContext)4380 PVMFStatus PVPlayerEngine::DoQuerySourceFormatType(PVCommandId aCmdId, OsclAny* aCmdContext)
4381 {
4382 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
4383 (0, "PVPlayerEngine::DoQuerySourceFormatType() Tick=%d", OsclTickCount::TickCount()));
4384
4385 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQuerySourceFormatType() In"));
4386
4387 // Use the recognizer if the source format type is unknown
4388 OSCL_ASSERT(iDataSource != NULL);
4389 PVPlayerEngineContext* context = AllocateEngineContext(NULL, NULL, NULL, aCmdId, aCmdContext, PVP_CMD_QUERYSOURCEFORMATTYPE);
4390 PVMFStatus retval = PVMFSuccess;
4391 int32 leavecode = 0;
4392
4393 OsclAny * opaqueData = iDataSource->GetDataSourceContextData();
4394 PVInterface* pvInterface = OSCL_STATIC_CAST(PVInterface*, opaqueData);
4395 PVInterface* SourceContextData = NULL;
4396 PVUuid SourceContextDataUuid(PVMF_SOURCE_CONTEXT_DATA_UUID);
4397 PVMFCPMPluginAccessInterfaceFactory * DataStreamDataFactory = NULL;
4398
4399 if (pvInterface != NULL && pvInterface->queryInterface(SourceContextDataUuid, SourceContextData))
4400 {
4401 PVMFSourceContextData * aSourceContextData = OSCL_STATIC_CAST(PVMFSourceContextData*, SourceContextData);
4402 PVMFSourceContextDataCommon * aSourceContextDataCommon = aSourceContextData->CommonData();
4403 if (aSourceContextDataCommon)
4404 {
4405 DataStreamDataFactory = aSourceContextDataCommon->iRecognizerDataStreamFactory;
4406 }
4407 }
4408
4409 if (DataStreamDataFactory)
4410 {
4411 OSCL_TRY(leavecode, retval = iPlayerRecognizerRegistry.QueryFormatType(DataStreamDataFactory, *this, (OsclAny*) context));
4412 OSCL_FIRST_CATCH_ANY(leavecode,
4413 FreeEngineContext(context);
4414 return PVMFErrNotSupported;
4415 );
4416 }
4417 else
4418 {
4419 OSCL_TRY(leavecode, retval = iPlayerRecognizerRegistry.QueryFormatType(iDataSource->GetDataSourceURL(), *this, (OsclAny*) context));
4420 OSCL_FIRST_CATCH_ANY(leavecode,
4421 FreeEngineContext(context);
4422 return PVMFErrNotSupported;
4423 );
4424 }
4425
4426 if (retval != PVMFSuccess)
4427 {
4428 FreeEngineContext(context);
4429 }
4430
4431 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoQuerySourceFormatType() Out"));
4432 return retval;
4433 }
4434
4435
DoSetupSourceNode(PVCommandId aCmdId,OsclAny * aCmdContext)4436 PVMFStatus PVPlayerEngine::DoSetupSourceNode(PVCommandId aCmdId, OsclAny* aCmdContext)
4437 {
4438 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
4439 (0, "PVPlayerEngine::DoSetupSourceNode() Tick=%d", OsclTickCount::TickCount()));
4440
4441 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetupSourceNode() In"));
4442
4443 OSCL_ASSERT(iDataSource != NULL);
4444
4445 if (iSourceNode == NULL)
4446 {
4447 PVMFFormatType outputformattype = PVMF_MIME_FORMAT_UNKNOWN ;
4448
4449 Oscl_Vector<PVUuid, OsclMemAllocator> foundUuids;
4450 // Query the node registry
4451 if (iPlayerNodeRegistry.QueryRegistry(iSourceFormatType, outputformattype, foundUuids) == PVMFSuccess)
4452 {
4453 if (foundUuids.empty())
4454 {
4455 // No matching node found
4456 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
4457 (0, "PVPlayerEngine::DoSetupSourceNode() Query Regsitry successful, No matching source node found."));
4458 return PVMFErrNotSupported;
4459 }
4460
4461 int32 leavecode = 0;
4462 OSCL_TRY(leavecode, iSourceNode = iPlayerNodeRegistry.CreateNode(foundUuids[0]));
4463 OSCL_FIRST_CATCH_ANY(leavecode,
4464 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupDecNode() Error in creating SourceNode"));
4465 return PVMFFailure;);
4466
4467 iNodeUuids.push_back(PVPlayerEngineUuidNodeMapping(foundUuids[0], iSourceNode));
4468
4469 if (iSourceNode == NULL)
4470 {
4471 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() Source node create failed"));
4472 return PVMFErrNoMemory;
4473 }
4474 }
4475 else
4476 {
4477 // Registry query failed
4478 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() Registry query for source node failed"));
4479 return PVMFErrNotSupported;
4480 }
4481 }
4482
4483 if (iSourceNode->ThreadLogon() != PVMFSuccess)
4484 {
4485 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() ThreadLogon() on the source node failed"));
4486 OSCL_ASSERT(false);
4487 return PVMFFailure;
4488 }
4489
4490 PVMFNodeSessionInfo nodesessioninfo(this, this, (OsclAny*)iSourceNode, this, (OsclAny*)iSourceNode);
4491 int32 leavecode = 0;
4492 OSCL_TRY(leavecode, iSourceNodeSessionId = iSourceNode->Connect(nodesessioninfo));
4493 OSCL_FIRST_CATCH_ANY(leavecode,
4494 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() Connect on iSourceNode did a leave!"));
4495 OSCL_ASSERT(false);
4496 return PVMFFailure);
4497
4498 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryInitIF);
4499
4500 PVUuid sourceinituuid = PVMF_DATA_SOURCE_INIT_INTERFACE_UUID;
4501 leavecode = 0;
4502 PVMFCommandId cmdid = -1;
4503 iSourceNodePVInterfaceInit = NULL;
4504 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, sourceinituuid, iSourceNodePVInterfaceInit, (OsclAny*)context));
4505 OSCL_FIRST_CATCH_ANY(leavecode,
4506 iSourceNodePVInterfaceInit = NULL;
4507 FreeEngineContext(context);
4508 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetupSourceNode() QueryInterface on iSourceNode did a leave!"));
4509 return PVMFFailure);
4510
4511 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetupSourceNode() Out"));
4512 return PVMFSuccess;
4513 }
4514
4515
DoSourceNodeQueryTrackSelIF(PVCommandId aCmdId,OsclAny * aCmdContext)4516 PVMFStatus PVPlayerEngine::DoSourceNodeQueryTrackSelIF(PVCommandId aCmdId, OsclAny* aCmdContext)
4517 {
4518 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
4519 (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Tick=%d", OsclTickCount::TickCount()));
4520
4521 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() In"));
4522
4523 int32 leavecode = 0;
4524
4525 if (iDataSource->GetDataSourceType() == PVP_DATASRCTYPE_URL)
4526 {
4527 // Setup the source node via the initialization IF
4528 OSCL_ASSERT(iSourceFormatType != PVMF_MIME_FORMAT_UNKNOWN);
4529
4530 OSCL_wHeapString<OsclMemAllocator> sourceURL;
4531 // In case the URL starts with file:// skip it
4532 OSCL_wStackString<8> fileScheme(_STRLIT_WCHAR("file"));
4533 OSCL_wStackString<8> schemeDelimiter(_STRLIT_WCHAR("://"));
4534 const oscl_wchar* actualURL = NULL;
4535
4536 if (oscl_strncmp(fileScheme.get_cstr(), iDataSource->GetDataSourceURL().get_cstr(), 4) == 0)
4537 {
4538 actualURL = oscl_strstr(iDataSource->GetDataSourceURL().get_cstr(), schemeDelimiter.get_cstr());
4539 if (actualURL == NULL)
4540 {
4541 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Unable to skip over file://"));
4542 return PVMFErrArgument;
4543 }
4544 //skip over ://
4545 actualURL += schemeDelimiter.get_size();
4546 sourceURL += actualURL;
4547 }
4548 else
4549 {
4550 sourceURL += iDataSource->GetDataSourceURL().get_cstr();
4551 }
4552
4553 PVMFStatus retval = iSourceNodeInitIF->SetSourceInitializationData(sourceURL, iSourceFormatType, iDataSource->GetDataSourceContextData());
4554 if (retval != PVMFSuccess)
4555 {
4556 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() SetSourceInitializationData failed"));
4557 return PVMFFailure;
4558 }
4559 // Set Playback Clock
4560 retval = iSourceNodeInitIF->SetClientPlayBackClock(&iPlaybackClock);
4561 if (retval != PVMFSuccess)
4562 {
4563 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() SetClientPlayBackClock failed!"));
4564 return PVMFFailure;
4565 }
4566 }
4567 else
4568 {
4569 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Data source type not supported yet so asserting"));
4570 OSCL_ASSERT(false);
4571 return PVMFFailure;
4572 }
4573
4574 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryTrackSelIF);
4575
4576 // Query the source node for the track selection IF
4577 PVUuid trackseluuid = PVMF_TRACK_SELECTION_INTERFACE_UUID;
4578 PVMFCommandId cmdid = -1;
4579 leavecode = 0;
4580 iSourceNodePVInterfaceTrackSel = NULL;
4581 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, trackseluuid, iSourceNodePVInterfaceTrackSel, (OsclAny*)context));
4582 OSCL_FIRST_CATCH_ANY(leavecode,
4583 iSourceNodePVInterfaceTrackSel = NULL;
4584 FreeEngineContext(context);
4585 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() QueryInterface on iSourceNode did a leave!"));
4586 return PVMFFailure);
4587
4588 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryTrackSelIF() Out"));
4589 return PVMFSuccess;
4590 }
4591
4592
DoSourceNodeQueryInterfaceOptional(PVCommandId aCmdId,OsclAny * aCmdContext)4593 PVMFStatus PVPlayerEngine::DoSourceNodeQueryInterfaceOptional(PVCommandId aCmdId, OsclAny* aCmdContext)
4594 {
4595 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
4596 (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
4597
4598 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() In"));
4599
4600 PVPlayerEngineContext* context = NULL;
4601 PVMFCommandId cmdid = -1;
4602 int32 leavecode = 0;
4603
4604 iNumPendingNodeCmd = 0;
4605
4606 // Query for Track Level Info IF
4607 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryTrackLevelInfoIF);
4608 PVUuid tracklevelinfouuid = PVMF_TRACK_LEVEL_INFO_INTERFACE_UUID;
4609 cmdid = -1;
4610 leavecode = 0;
4611 iSourceNodePVInterfaceTrackLevelInfo = NULL;
4612 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, tracklevelinfouuid, iSourceNodePVInterfaceTrackLevelInfo, (OsclAny*)context));
4613 if (leavecode)
4614 {
4615 iSourceNodePVInterfaceTrackLevelInfo = NULL;
4616 FreeEngineContext(context);
4617 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4618 }
4619 else
4620 {
4621 ++iNumPendingNodeCmd;
4622 }
4623
4624 // Query for Playback Control IF
4625 context = NULL;
4626 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryPBCtrlIF);
4627 PVUuid pbctrluuid = PvmfDataSourcePlaybackControlUuid;
4628 cmdid = -1;
4629 leavecode = 0;
4630 iSourceNodePVInterfacePBCtrl = NULL;
4631 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, pbctrluuid, iSourceNodePVInterfacePBCtrl, (OsclAny*)context));
4632 if (leavecode)
4633 {
4634 iSourceNodePVInterfacePBCtrl = NULL;
4635 FreeEngineContext(context);
4636 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4637 }
4638 else
4639 {
4640 ++iNumPendingNodeCmd;
4641 }
4642
4643 // Query for direction control IF
4644 context = NULL;
4645 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryDirCtrlIF);
4646 PVUuid dirctrluuid = PvmfDataSourceDirectionControlUuid;
4647 cmdid = -1;
4648 leavecode = 0;
4649 iSourceNodePVInterfaceDirCtrl = NULL;
4650 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, dirctrluuid, iSourceNodePVInterfaceDirCtrl, (OsclAny*)context));
4651 if (leavecode)
4652 {
4653 iSourceNodePVInterfaceDirCtrl = NULL;
4654 FreeEngineContext(context);
4655 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4656 }
4657 else
4658 {
4659 ++iNumPendingNodeCmd;
4660 }
4661
4662 // Query for Metadata IF
4663 context = NULL;
4664 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryMetadataIF);
4665 PVUuid metadatauuid = KPVMFMetadataExtensionUuid;
4666 cmdid = -1;
4667 leavecode = 0;
4668 iSourceNodePVInterfaceMetadataExt = NULL;
4669 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, metadatauuid, iSourceNodePVInterfaceMetadataExt, (OsclAny*)context));
4670 if (leavecode)
4671 {
4672 iSourceNodePVInterfaceMetadataExt = NULL;
4673 FreeEngineContext(context);
4674 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4675 }
4676 else
4677 {
4678 ++iNumPendingNodeCmd;
4679 }
4680
4681 // Query for Cap-Config IF
4682 context = NULL;
4683 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryCapConfigIF);
4684 PVUuid capconfiguuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID;
4685 cmdid = -1;
4686 leavecode = 0;
4687 iSourceNodePVInterfaceCapConfig = NULL;
4688 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, capconfiguuid, iSourceNodePVInterfaceCapConfig, (OsclAny*)context));
4689 if (leavecode)
4690 {
4691 iSourceNodePVInterfaceCapConfig = NULL;
4692 FreeEngineContext(context);
4693 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4694 }
4695 else
4696 {
4697 ++iNumPendingNodeCmd;
4698 }
4699
4700 // Query for CPM License interface
4701 context = NULL;
4702 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryCPMLicenseIF);
4703 PVUuid licUuid = PVMFCPMPluginLicenseInterfaceUuid;
4704 cmdid = -1;
4705 leavecode = 0;
4706 iSourceNodePVInterfaceCPMLicense = NULL;
4707 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, licUuid, iSourceNodePVInterfaceCPMLicense, (OsclAny*)context));
4708 if (leavecode)
4709 {
4710 iSourceNodePVInterfaceCPMLicense = NULL;
4711 FreeEngineContext(context);
4712 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4713 }
4714 else
4715 {
4716 ++iNumPendingNodeCmd;
4717 }
4718
4719 // Query for source node registry init extension IF
4720 context = NULL;
4721 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQuerySrcNodeRegInitIF);
4722 PVUuid regInitUuid = PVMF_DATA_SOURCE_NODE_REGISRTY_INIT_INTERFACE_UUID;
4723 cmdid = -1;
4724 leavecode = 0;
4725 iSourceNodePVInterfaceRegInit = NULL;
4726 OSCL_TRY(leavecode, cmdid = iSourceNode->QueryInterface(iSourceNodeSessionId, regInitUuid, iSourceNodePVInterfaceRegInit, (OsclAny*)context));
4727 if (leavecode)
4728 {
4729 iSourceNodePVInterfaceRegInit = NULL;
4730 FreeEngineContext(context);
4731 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() QueryInterface on iSourceNode did a leave!"));
4732 }
4733 else
4734 {
4735 ++iNumPendingNodeCmd;
4736 }
4737
4738 if (iNumPendingNodeCmd > 0)
4739 {
4740 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() Out"));
4741 return PVMFSuccess;
4742 }
4743 else
4744 {
4745 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryInterfaceOptional() Out No pending QueryInterface() on source node"));
4746 return PVMFFailure;
4747 }
4748 }
4749
DoGetMetadataKey(PVPlayerEngineCommand & aCmd)4750 PVMFStatus PVPlayerEngine::DoGetMetadataKey(PVPlayerEngineCommand& aCmd)
4751 {
4752 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
4753 (0, "PVPlayerEngine::DoGetMetadataKey() Tick=%d", OsclTickCount::TickCount()));
4754
4755 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataKey() In"));
4756
4757 if (GetPVPlayerState() == PVP_STATE_ERROR)
4758 {
4759 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataKey() Wrong engine state."));
4760 return PVMFFailure;
4761 }
4762
4763 iGetMetadataKeysParam.iKeyList = (PVPMetadataList*)(aCmd.GetParam(0).pOsclAny_value);
4764 iGetMetadataKeysParam.iStartingKeyIndex = aCmd.GetParam(1).int32_value;
4765 iGetMetadataKeysParam.iMaxKeyEntries = aCmd.GetParam(2).int32_value;
4766 iGetMetadataKeysParam.iQueryKey = aCmd.GetParam(3).pChar_value;
4767
4768 if (iGetMetadataKeysParam.iKeyList == NULL)
4769 {
4770 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataKey() Passed in parameter invalid."));
4771 return PVMFErrArgument;
4772 }
4773
4774 if (iGetMetadataKeysParam.iMaxKeyEntries < -1 || iGetMetadataKeysParam.iMaxKeyEntries == 0 || iGetMetadataKeysParam.iStartingKeyIndex < 0)
4775 {
4776 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataKey() Passed in parameter invalid."));
4777 return PVMFErrArgument;
4778 }
4779
4780 // Determine which node's metadata interface to start the retrieval based on the starting index
4781 uint32 i = 0;
4782 int32 totalnumkey = 0;
4783 uint32 nodestartindex = 0;
4784 while (i < iMetadataIFList.size())
4785 {
4786 int32 numkey = iMetadataIFList[i].iInterface->GetNumMetadataKeys(iGetMetadataKeysParam.iQueryKey);
4787 if (iGetMetadataKeysParam.iStartingKeyIndex < (totalnumkey + numkey))
4788 {
4789 // Found the node to start the key retrieval
4790 // Determine the start index for this node
4791 nodestartindex = iGetMetadataKeysParam.iStartingKeyIndex - totalnumkey;
4792 break;
4793 }
4794 else
4795 {
4796 // Keep checking
4797 totalnumkey += numkey;
4798 ++i;
4799 }
4800 }
4801
4802 // Check if the search succeeded
4803 if (i == iMetadataIFList.size() || iMetadataIFList.size() == 0)
4804 {
4805 // Starting index is too large or there is no metadata interface available
4806 return PVMFErrArgument;
4807 }
4808
4809 // Retrieve the metadata key from the first node
4810 PVPlayerEngineContext* context = AllocateEngineContext(iMetadataIFList[i].iEngineDatapath, iMetadataIFList[i].iNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_GetNodeMetadataKey);
4811 PVMFMetadataExtensionInterface* metadataif = iMetadataIFList[i].iInterface;
4812 PVMFSessionId sessionid = iMetadataIFList[i].iSessionId;
4813 PVMFCommandId cmdid = -1;
4814 cmdid = metadataif->GetNodeMetadataKeys(sessionid,
4815 *(iGetMetadataKeysParam.iKeyList),
4816 nodestartindex,
4817 iGetMetadataKeysParam.iMaxKeyEntries,
4818 iGetMetadataKeysParam.iQueryKey,
4819 (OsclAny*)context);
4820 if (cmdid == -1)
4821 {
4822 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
4823 (0, "PVPlayerEngine::DoGetMetadataKey() GetNodeMetadataKeys failed"));
4824 return PVMFFailure;
4825 }
4826
4827 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataKey() Out"));
4828
4829 // Save the current metadata value retrieval status
4830 iGetMetadataKeysParam.iCurrentInterfaceIndex = i;
4831 iGetMetadataKeysParam.iNumKeyEntriesToFill = iGetMetadataKeysParam.iMaxKeyEntries;
4832 iGetMetadataKeysParam.iNumKeyEntriesInList = iGetMetadataKeysParam.iKeyList->size();
4833
4834 return PVMFSuccess;
4835 }
4836
4837
DoGetMetadataValue(PVPlayerEngineCommand & aCmd)4838 PVMFStatus PVPlayerEngine::DoGetMetadataValue(PVPlayerEngineCommand& aCmd)
4839 {
4840 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
4841 (0, "PVPlayerEngine::DoGetMetadataValue() Tick=%d", OsclTickCount::TickCount()));
4842
4843 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataValue() In"));
4844
4845 if (GetPVPlayerState() == PVP_STATE_ERROR)
4846 {
4847 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataValue() Wrong engine state"));
4848 return PVMFErrInvalidState;
4849 }
4850
4851 if (iReleaseMetadataValuesPending)
4852 {
4853 // App has called GetMetadataValues without calling ReleaseMetadata values on previous list. Wrong
4854 // usage. Failure needs to be returned in this case.
4855 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
4856 (0, "PVPlayerEngine::GetMetadataValues() Wrong usage, called again without releasing earlier metadata list"));
4857 return PVMFErrReleaseMetadataValueNotDone;
4858 }
4859
4860 iGetMetadataValuesParam.iKeyList = (PVPMetadataList*)(aCmd.GetParam(0).pOsclAny_value);
4861 iGetMetadataValuesParam.iStartingValueIndex = aCmd.GetParam(1).int32_value;
4862 iGetMetadataValuesParam.iMaxValueEntries = aCmd.GetParam(2).int32_value;
4863 iGetMetadataValuesParam.iNumAvailableValues = (int32*)(aCmd.GetParam(3).pOsclAny_value);
4864 iGetMetadataValuesParam.iValueList = (Oscl_Vector<PvmiKvp, OsclMemAllocator>*)(aCmd.GetParam(4).pOsclAny_value);
4865 iMetadataValuesCopiedInCallBack = aCmd.GetParam(5).bool_value;
4866
4867 if (iGetMetadataValuesParam.iKeyList == NULL || iGetMetadataValuesParam.iValueList == NULL || iGetMetadataValuesParam.iNumAvailableValues == NULL)
4868 {
4869 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataValue() Passed in parameter invalid."));
4870 return PVMFErrArgument;
4871 }
4872
4873 if (iGetMetadataValuesParam.iMaxValueEntries < -1 || iGetMetadataValuesParam.iMaxValueEntries == 0 || iGetMetadataValuesParam.iStartingValueIndex < 0)
4874 {
4875 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetMetadataValue() Passed in parameter invalid."));
4876 return PVMFErrArgument;
4877 }
4878
4879 // Determine which node's metadata interface to start the retrieval based on the starting index
4880 uint32 i = 0;
4881 int32 totalnumvalue = 0;
4882 uint32 nodestartindex = 0;
4883 while (i < iMetadataIFList.size())
4884 {
4885 int32 numvalue = iMetadataIFList[i].iInterface->GetNumMetadataValues(*(iGetMetadataValuesParam.iKeyList));
4886 if (iGetMetadataValuesParam.iStartingValueIndex < (totalnumvalue + numvalue))
4887 {
4888 // Found the node to start the value retrieval
4889 // Determine the start index for this node
4890 nodestartindex = iGetMetadataValuesParam.iStartingValueIndex - totalnumvalue;
4891 // Save the number of available values so far
4892 *(iGetMetadataValuesParam.iNumAvailableValues) = totalnumvalue + numvalue;
4893 break;
4894 }
4895 else
4896 {
4897 // Keep checking
4898 totalnumvalue += numvalue;
4899 ++i;
4900 }
4901 }
4902
4903 // Check if the search succeeded
4904 if (i == iMetadataIFList.size() || iMetadataIFList.size() == 0)
4905 {
4906 // Starting index is too large or there is no metadata interface available
4907 return PVMFErrArgument;
4908 }
4909
4910 // Retrieve the metadata value from the first node
4911 PVPlayerEngineContext* context = AllocateEngineContext(iMetadataIFList[i].iEngineDatapath, iMetadataIFList[i].iNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_GetNodeMetadataValue);
4912 PVMFMetadataExtensionInterface* metadataif = iMetadataIFList[i].iInterface;
4913 PVMFSessionId sessionid = iMetadataIFList[i].iSessionId;
4914 PVMFCommandId cmdid = -1;
4915 cmdid = metadataif->GetNodeMetadataValues(sessionid,
4916 *(iGetMetadataValuesParam.iKeyList),
4917 *(iGetMetadataValuesParam.iValueList),
4918 nodestartindex,
4919 iGetMetadataValuesParam.iMaxValueEntries,
4920 (OsclAny*)context);
4921
4922 if (cmdid == -1)
4923 {
4924 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
4925 (0, "PVPlayerEngine::DoGetMetadataValue() GetNodeMetadataValues failed"));
4926 return PVMFFailure;
4927 }
4928
4929 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetMetadataValue() Out"));
4930
4931 // Save the current metadata value retrieval status
4932 iGetMetadataValuesParam.iCurrentInterfaceIndex = i;
4933 iGetMetadataValuesParam.iNumValueEntriesToFill = iGetMetadataValuesParam.iMaxValueEntries;
4934 iGetMetadataValuesParam.iNumValueEntriesInList = iGetMetadataValuesParam.iValueList->size();
4935
4936 return PVMFSuccess;
4937 }
4938
DoReleaseMetadataValues(PVPlayerEngineCommand & aCmd)4939 PVMFStatus PVPlayerEngine::DoReleaseMetadataValues(PVPlayerEngineCommand& aCmd)
4940 {
4941 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
4942 (0, "PVPlayerEngine::DoReleaseMetadataValues() Tick=%d", OsclTickCount::TickCount()));
4943
4944 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReleaseMetadataValues() In"));
4945
4946 if (GetPVPlayerState() == PVP_STATE_ERROR ||
4947 GetPVPlayerState() == PVP_STATE_IDLE)
4948 {
4949 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoReleaseMetadataValues() Wrong engine state"));
4950 return PVMFErrInvalidState;
4951 }
4952
4953 iGetMetadataValuesParam.iValueList = (Oscl_Vector<PvmiKvp, OsclMemAllocator>*)(aCmd.GetParam(0).pOsclAny_value);
4954
4955 if (iGetMetadataValuesParam.iValueList == NULL)
4956 {
4957 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoReleaseMetadataValues() Passed in parameter invalid."));
4958 return PVMFErrArgument;
4959 }
4960
4961 // Release the memory allocated for the metadata values
4962 while (iMetadataValueReleaseList.empty() == false)
4963 {
4964 PVMFMetadataExtensionInterface* mdif = iMetadataIFList[iMetadataValueReleaseList[0].iMetadataIFListIndex].iInterface;
4965 OSCL_ASSERT(mdif != NULL);
4966 mdif->ReleaseNodeMetadataValues(*(iGetMetadataValuesParam.iValueList), iMetadataValueReleaseList[0].iStartIndex, iMetadataValueReleaseList[0].iEndIndex);
4967 iMetadataValueReleaseList.erase(iMetadataValueReleaseList.begin());
4968 }
4969
4970 iReleaseMetadataValuesPending = false;
4971
4972 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4973
4974 return PVMFSuccess;
4975 }
4976
DoInit(PVPlayerEngineCommand & aCmd)4977 PVMFStatus PVPlayerEngine::DoInit(PVPlayerEngineCommand& aCmd)
4978 {
4979 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
4980 (0, "PVPlayerEngine::DoInit() Tick=%d", OsclTickCount::TickCount()));
4981
4982 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoInit() In"));
4983
4984 if (GetPVPlayerState() == PVP_STATE_INITIALIZED)
4985 {
4986 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() Engine already in Initialized State"));
4987 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
4988 return PVMFSuccess;
4989 }
4990
4991 if ((GetPVPlayerState() != PVP_STATE_IDLE) || (iSourceNode == NULL))
4992 {
4993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() Wrong engine state"));
4994 return PVMFErrInvalidState;
4995 }
4996
4997 iRollOverState = RollOverStateIdle;
4998
4999 PVMFStatus retval = DoSourceNodeInit(aCmd.GetCmdId(), aCmd.GetContext());
5000
5001 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoInit() Out"));
5002
5003 if (retval == PVMFSuccess)
5004 {
5005 SetEngineState(PVP_ENGINE_STATE_INITIALIZING);
5006 return PVMFSuccess;
5007 }
5008 else
5009 {
5010 bool ehPending = CheckForPendingErrorHandlingCmd();
5011 if (ehPending)
5012 {
5013 // there should be no error handling queued.
5014 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() Already EH pending, should never happen"));
5015 return PVMFPending;
5016 }
5017 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoInit() DoSourceNodeInit failed, Add EH command"));
5018 iCommandCompleteStatusInErrorHandling = retval;
5019 iCommandCompleteErrMsgInErrorHandling = NULL;
5020 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
5021 return PVMFPending;
5022 }
5023 }
5024
5025
DoSourceNodeInit(PVCommandId aCmdId,OsclAny * aCmdContext)5026 PVMFStatus PVPlayerEngine::DoSourceNodeInit(PVCommandId aCmdId, OsclAny* aCmdContext)
5027 {
5028 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
5029 (0, "PVPlayerEngine::DoSourceNodeInit() Tick=%d", OsclTickCount::TickCount()));
5030
5031 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeInit() In"));
5032
5033 OSCL_ASSERT(iSourceNode != NULL);
5034
5035 int32 leavecode = 0;
5036
5037 // Initialize the source node
5038 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeInit);
5039
5040 leavecode = 0;
5041 PVMFCommandId cmdid = -1;
5042 OSCL_TRY(leavecode, cmdid = iSourceNode->Init(iSourceNodeSessionId, (OsclAny*)context));
5043 OSCL_FIRST_CATCH_ANY(leavecode,
5044 FreeEngineContext(context);
5045 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeInit() Init on iSourceNode did a leave!"));
5046 return PVMFFailure);
5047
5048 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeInit() Out"));
5049
5050 return PVMFSuccess;
5051 }
5052
5053
DoSourceNodeGetDurationValue(PVCommandId aCmdId,OsclAny * aCmdContext)5054 PVMFStatus PVPlayerEngine::DoSourceNodeGetDurationValue(PVCommandId aCmdId, OsclAny* aCmdContext)
5055 {
5056 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetDurationValue() In"));
5057
5058
5059 // Create a key list with just duration key
5060 iSourceDurationKeyList.clear();
5061 OSCL_HeapString<OsclMemAllocator> tmpstr = _STRLIT_CHAR("duration");
5062 iSourceDurationKeyList.push_back(tmpstr);
5063 // Clear the value list
5064 iSourceDurationValueList.clear();
5065
5066 if (iSourceNodeMetadataExtIF == NULL)
5067 {
5068 return PVMFErrArgument;
5069 }
5070
5071 // Call GetNodeMetadataValues on the source node to retrieve duration
5072 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeGetDurationValue);
5073
5074 int32 leavecode = 0;
5075 PVMFCommandId cmdid = -1;
5076 OSCL_TRY(leavecode, cmdid = iSourceNodeMetadataExtIF->GetNodeMetadataValues(iSourceNodeSessionId,
5077 iSourceDurationKeyList,
5078 iSourceDurationValueList,
5079 0 /*starting index*/, 1 /*max entries*/, (OsclAny*)context));
5080 OSCL_FIRST_CATCH_ANY(leavecode,
5081 FreeEngineContext(context);
5082 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeGetDurationValue() GetNodeMetadataValues on iSourceNode did a leave!"));
5083 return PVMFFailure);
5084
5085 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetDurationValue() Out"));
5086 return PVMFSuccess;
5087 }
5088
DoSourceNodeRollOver(PVCommandId aCmdId,OsclAny * aCmdContext)5089 PVMFStatus PVPlayerEngine::DoSourceNodeRollOver(PVCommandId aCmdId, OsclAny* aCmdContext)
5090 {
5091 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeRollOver() In"));
5092 /* Clean up any exisiting source node */
5093 DoSourceNodeCleanup();
5094
5095 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeRollOver() DoSourceNodeCleanup Complete"));
5096 if (CheckForSourceRollOver())
5097 {
5098 if (iDataSource->GetAlternateSourceFormatType(iSourceFormatType,
5099 iAlternateSrcFormatIndex))
5100 {
5101 uint8 localbuffer[8];
5102 oscl_memset(localbuffer, 0, 8);
5103 localbuffer[0] = 1;
5104 oscl_memcpy(&localbuffer[4], &iSourceFormatType, sizeof(uint32));
5105
5106 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
5107 PVMFBasicErrorInfoMessage* infomsg =
5108 OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoAttemptingSourceRollOver, puuid, NULL));
5109 SendInformationalEvent(PVMFInfoSourceFormatNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg), NULL, localbuffer, 8);
5110 infomsg->removeRef();
5111
5112 iAlternateSrcFormatIndex++;
5113 PVMFStatus status = DoSetupSourceNode(aCmdId, aCmdContext);
5114 if (status != PVMFSuccess)
5115 {
5116 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeRollOver() SourceNodeRollOver Failed, return status"));
5117 return status;
5118 }
5119 //roll over pending
5120 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeRollOver() SourceNodeRollOver In Progress"));
5121 return PVMFPending;
5122 }
5123 }
5124 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeRollOver() Invalid State"));
5125 return PVMFErrInvalidState;
5126 }
5127
DoAcquireLicense(PVPlayerEngineCommand & aCmd)5128 PVMFStatus PVPlayerEngine::DoAcquireLicense(PVPlayerEngineCommand& aCmd)
5129 {
5130 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
5131 (0, "PVPlayerEngine::DoAcquireLicense() Tick=%d", OsclTickCount::TickCount()));
5132
5133 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAcquireLicense() In"));
5134
5135 // Retrieve the command parameters and validate
5136 iCPMAcquireLicenseParam.iContentNameChar = NULL;
5137 iCPMAcquireLicenseParam.iContentNameWChar = NULL;
5138 iCPMAcquireLicenseParam.iTimeoutMsec = (-1);
5139 iCPMAcquireLicenseParam.iLicenseData = NULL;
5140 iCPMAcquireLicenseParam.iLicenseDataSize = 0;
5141
5142 if (aCmd.GetParam(0).pOsclAny_value != NULL)
5143 {
5144 iCPMAcquireLicenseParam.iLicenseData = aCmd.GetParam(0).pOsclAny_value;
5145 }
5146
5147 if (aCmd.GetParam(1).uint32_value != 0)
5148 {
5149 iCPMAcquireLicenseParam.iLicenseDataSize = aCmd.GetParam(1).uint32_value;
5150 }
5151
5152 if (aCmd.GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR)
5153 {
5154 iCPMAcquireLicenseParam.iContentNameWChar = aCmd.GetParam(2).pWChar_value;
5155 }
5156 else
5157 {
5158 iCPMAcquireLicenseParam.iContentNameChar = aCmd.GetParam(2).pChar_value;
5159 }
5160 iCPMAcquireLicenseParam.iTimeoutMsec = aCmd.GetParam(3).int32_value;
5161
5162 if (iCPMAcquireLicenseParam.iContentNameWChar == NULL && iCPMAcquireLicenseParam.iContentNameChar == NULL)
5163 {
5164 // Content name not specified
5165 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Content name not specified."));
5166 return PVMFErrArgument;
5167 }
5168
5169 if (iCPMAcquireLicenseParam.iTimeoutMsec < -1)
5170 {
5171 // Timeout parameter not valid
5172 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Timeout value not valid."));
5173 return PVMFErrArgument;
5174 }
5175
5176 // To acquire license, player data source and local data source need to be available
5177 if (iDataSource == NULL)
5178 {
5179 // Player data source not available
5180 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Player data source not specified."));
5181 return PVMFErrNotReady;
5182 }
5183 if (iDataSource->GetDataSourceContextData() == NULL)
5184 {
5185 // Pointer to the local data source if not available
5186 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() Local data source in player data source not specified."));
5187 return PVMFErrBadHandle;
5188 }
5189
5190 //If the license interface is available from the source node, use that.
5191 if (iSourceNodeCPMLicenseIF != NULL)
5192 {
5193 PVMFStatus status = DoSourceNodeGetLicense(aCmd.GetCmdId(), aCmd.GetContext());
5194 if (status != PVMFSuccess)
5195 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAcquireLicense() DoSourceNodeGetLicense failed."));
5196
5197 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAcquireLicense() Out"));
5198 return status;
5199 }
5200
5201 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAcquireLicense() Out"));
5202 // if the license interface is not available from the source node, fail the command
5203 return PVMFFailure;
5204 }
5205
DoCancelAcquireLicense(PVPlayerEngineCommand & aCmd)5206 void PVPlayerEngine::DoCancelAcquireLicense(PVPlayerEngineCommand& aCmd)
5207 {
5208
5209 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
5210 (0, "PVPlayerEngine::DoCancelAcquireLicense() Tick=%d", OsclTickCount::TickCount()));
5211
5212 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAcquireLicense() In"));
5213
5214 /* Engine cannot be processing another cancel command */
5215 OSCL_ASSERT(iCmdToDlaCancel.empty() == true);
5216
5217 PVMFCommandId id = aCmd.GetParam(0).int32_value;
5218 PVMFStatus status = PVMFSuccess;
5219
5220 if (iCurrentCmd.size() == 1)
5221 {
5222 /* First save the current command being processed */
5223 PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
5224
5225 /* First check "current" command if any */
5226 if (id == iCurrentCmd[0].GetCmdId())
5227 {
5228 /* Cancel the current command first */
5229 if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR
5230 || iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR)
5231 {
5232 /* Make the CancelAll() command the current command */
5233 iCmdToDlaCancel.push_front(aCmd);
5234 /* Properly cancel a command being currently processed */
5235 if (iSourceNodeCPMLicenseIF != NULL)
5236 {
5237 /* Cancel the GetLicense */
5238 PVPlayerEngineContext* context = NULL;
5239 PVMFCommandId cmdid = -1;
5240 int32 leavecode = 0;
5241 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_SourceNodeCancelGetLicense);
5242
5243 OSCL_TRY(leavecode, cmdid = iSourceNodeCPMLicenseIF->CancelGetLicense(iSourceNodeSessionId, iCPMGetLicenseCmdId, (OsclAny*)context));
5244 if (leavecode)
5245 {
5246 FreeEngineContext(context);
5247 status = PVMFErrNotSupported;
5248 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() CancelGetLicense on iSourceNode did a leave!"));
5249 }
5250 }
5251 else
5252 {
5253 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() CPM plug-in registry in local data source not specified."));
5254 OSCL_ASSERT(false);
5255 status = PVMFErrBadHandle;
5256 }
5257 }
5258 else
5259 {
5260 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() Current cmd is not AquireLicense."));
5261 status = PVMFErrArgument;
5262 }
5263 }
5264 else
5265 {
5266 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() Current cmd ID is not equal with App specified cmd ID."));
5267 status = PVMFErrArgument;
5268 }
5269 if (status != PVMFSuccess)
5270 {
5271 /* We send error completetion for CancelAcquireLicense API*/
5272 iCurrentCmd.erase(iCurrentCmd.begin());
5273 iCurrentCmd.push_front(aCmd);
5274 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), status);
5275 iCurrentCmd.push_front(currentcmd);
5276 }
5277 }
5278 else
5279 {
5280 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCancelAcquireLicense() No Current cmd"));
5281 iCurrentCmd.push_front(aCmd);
5282 status = PVMFErrArgument;
5283 /* If we get here the command isn't queued so the cancel fails */
5284 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), status);
5285 }
5286
5287 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCancelAcquireLicense() Out"));
5288 return;
5289 }
5290
DoSourceNodeGetLicense(PVCommandId aCmdId,OsclAny * aCmdContext)5291 PVMFStatus PVPlayerEngine::DoSourceNodeGetLicense(PVCommandId aCmdId, OsclAny* aCmdContext)
5292 {
5293 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
5294 (0, "PVPlayerEngine::DoSourceNodeGetLicense() Tick=%d", OsclTickCount::TickCount()));
5295
5296 OSCL_UNUSED_ARG(aCmdId);
5297 OSCL_UNUSED_ARG(aCmdContext);
5298
5299 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetLicense() In"));
5300
5301 if (iSourceNodeCPMLicenseIF == NULL)
5302 {
5303 OSCL_ASSERT(false);
5304 return PVMFErrBadHandle;
5305 }
5306
5307 // Get the license
5308 PVPlayerEngineContext* context = NULL;
5309 int32 leavecode = 0;
5310 context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeGetLicense);
5311 if (iCPMAcquireLicenseParam.iContentNameChar)
5312 {
5313 // Use the char version
5314 iCPMContentNameStr = iCPMAcquireLicenseParam.iContentNameChar;
5315 OSCL_TRY(leavecode, iCPMGetLicenseCmdId = iSourceNodeCPMLicenseIF->GetLicense(iSourceNodeSessionId,
5316 iCPMContentNameStr,
5317 iCPMAcquireLicenseParam.iLicenseData,
5318 iCPMAcquireLicenseParam.iLicenseDataSize,
5319 iCPMAcquireLicenseParam.iTimeoutMsec,
5320 (OsclAny*)context));
5321 }
5322 else if (iCPMAcquireLicenseParam.iContentNameWChar)
5323 {
5324 // Use the wchar version
5325 iCPMContentNameWStr = iCPMAcquireLicenseParam.iContentNameWChar;
5326 OSCL_TRY(leavecode, iCPMGetLicenseCmdId = iSourceNodeCPMLicenseIF->GetLicense(iSourceNodeSessionId,
5327 iCPMContentNameWStr,
5328 iCPMAcquireLicenseParam.iLicenseData,
5329 iCPMAcquireLicenseParam.iLicenseDataSize,
5330 iCPMAcquireLicenseParam.iTimeoutMsec,
5331 (OsclAny*)context));
5332 }
5333 else
5334 {
5335 // This should not happen
5336 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeGetLicense() Content name not specified. Asserting"));
5337 OSCL_ASSERT(false);
5338 return PVMFErrArgument;
5339 }
5340
5341 if (leavecode)
5342 {
5343 FreeEngineContext(context);
5344 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeGetLicense() GetLicense on iSourceNode did a leave!"));
5345 }
5346 else
5347 {
5348 ++iNumPendingNodeCmd;
5349 }
5350
5351 if (iNumPendingNodeCmd <= 0)
5352 {
5353 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetLicense() Out No pending QueryInterface() on source node"));
5354 return PVMFFailure;
5355 }
5356
5357 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeGetLicense() Out"));
5358 return PVMFSuccess;
5359 }
5360
DoAddDataSink(PVPlayerEngineCommand & aCmd)5361 PVMFStatus PVPlayerEngine::DoAddDataSink(PVPlayerEngineCommand& aCmd)
5362 {
5363 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
5364 (0, "PVPlayerEngine::DoAddDataSink() Tick=%d", OsclTickCount::TickCount()));
5365
5366 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSink() In"));
5367
5368 if (GetPVPlayerState() != PVP_STATE_INITIALIZED)
5369 {
5370 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSink() Wrong engine state"));
5371 return PVMFErrInvalidState;
5372 }
5373
5374 if (aCmd.GetParam(0).pOsclAny_value == NULL)
5375 {
5376 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoAddDataSink() Passed in parameter invalid."));
5377 return PVMFErrArgument;
5378 }
5379
5380 PVPlayerDataSink* datasink = (PVPlayerDataSink*)(aCmd.GetParam(0).pOsclAny_value);
5381
5382 PVPlayerEngineDatapath newdatapath;
5383 newdatapath.iDataSink = datasink;
5384
5385 // Add a new engine datapath to the list for the data sink
5386 iDatapathList.push_back(newdatapath);
5387
5388 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
5389
5390 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoAddDataSink() Out"));
5391 return PVMFSuccess;
5392 }
5393
5394
DoSetPlaybackRange(PVPlayerEngineCommand & aCmd)5395 PVMFStatus PVPlayerEngine::DoSetPlaybackRange(PVPlayerEngineCommand& aCmd)
5396 {
5397 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
5398 (0, "PVPlayerEngine::DoSetPlaybackRange() Tick=%d", OsclTickCount::TickCount()));
5399
5400 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRange() In"));
5401
5402 PVMFStatus retval;
5403
5404 if (GetPVPlayerState() == PVP_STATE_ERROR)
5405 {
5406 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRange() Wrong engine state"));
5407 return PVMFErrInvalidState;
5408 }
5409
5410 if (aCmd.GetParam(2).bool_value)
5411 {
5412 // Queueing of playback range is not supported yet
5413 iQueuedRangePresent = false;
5414 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRange() Queued playback range is not supported yet"));
5415 return PVMFErrNotSupported;
5416 }
5417
5418 // Change the end position
5419 iCurrentEndPosition = aCmd.GetParam(1).playbackpos_value;
5420 retval = UpdateCurrentEndPosition(iCurrentEndPosition);
5421 if (retval != PVMFSuccess)
5422 {
5423 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRange() Changing end position failed"));
5424 return retval;
5425 }
5426
5427 if (aCmd.GetParam(0).playbackpos_value.iIndeterminate)
5428 {
5429 // Start position not specified so return as success
5430 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
5431 return PVMFSuccess;
5432 }
5433
5434 // reset repos related variables except the StreamID.
5435 ResetReposVariables(false);
5436 iStreamID++;
5437
5438 // Reset the paused-due-to-EOS flag
5439 iPlaybackPausedDueToEndOfClip = false;
5440
5441 // Change the begin position
5442 iCurrentBeginPosition = aCmd.GetParam(0).playbackpos_value;
5443 iTargetNPT = iCurrentBeginPosition.iPosValue.millisec_value;
5444 retval = UpdateCurrentBeginPosition(iCurrentBeginPosition, aCmd);
5445
5446 if (retval == PVMFSuccess)
5447 {
5448 // Notify completion of engine command
5449 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
5450 }
5451 else if (retval == PVMFPending)
5452 {
5453 // SetPlaybackRange command is still being processed
5454 // so change the return status so command is not completed yet
5455 retval = PVMFSuccess;
5456 }
5457
5458 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRange() Out"));
5459 return retval;
5460 }
5461
5462
UpdateCurrentEndPosition(PVPPlaybackPosition & aEndPos)5463 PVMFStatus PVPlayerEngine::UpdateCurrentEndPosition(PVPPlaybackPosition& aEndPos)
5464 {
5465 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentEndPosition() In"));
5466
5467 if (aEndPos.iIndeterminate)
5468 {
5469 // Disable end time checking if running
5470 if (iEndTimeCheckEnabled)
5471 {
5472 iEndTimeCheckEnabled = false;
5473 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
5474 }
5475 }
5476 else
5477 {
5478 // Convert the end time to milliseconds to have consistent units internally
5479 uint32 timems = 0;
5480 PVMFStatus retval = ConvertToMillisec(aEndPos, timems);
5481 if (retval != PVMFSuccess)
5482 {
5483 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentEndPosition() Converting to millisec failed"));
5484 return retval;
5485 }
5486 aEndPos.iPosValue.millisec_value = timems;
5487 aEndPos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
5488
5489 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentEndPosition() Changing end time to %d ms", timems));
5490
5491 // Enable the end time checking if not running
5492 if (!iEndTimeCheckEnabled)
5493 {
5494 iEndTimeCheckEnabled = true;
5495
5496 if (GetPVPlayerState() == PVP_STATE_STARTED)
5497 {
5498 // Determine the check cycle based on interval setting in milliseconds
5499 // and timer frequency of 100 millisec
5500 int32 checkcycle = iEndTimeCheckInterval / 100;
5501 if (checkcycle == 0)
5502 {
5503 ++checkcycle;
5504 }
5505 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
5506 iPollingCheckTimer->Request(PVPLAYERENGINE_TIMERID_ENDTIMECHECK, 0, checkcycle, this, true);
5507 }
5508 }
5509 }
5510
5511 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentEndPosition() Out"));
5512 return PVMFSuccess;
5513 }
5514
5515
UpdateCurrentBeginPosition(PVPPlaybackPosition & aBeginPos,PVPlayerEngineCommand & aCmd)5516 PVMFStatus PVPlayerEngine::UpdateCurrentBeginPosition(PVPPlaybackPosition& aBeginPos, PVPlayerEngineCommand& aCmd)
5517 {
5518 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() In"));
5519
5520 PVMFStatus retval = PVMFSuccess;
5521 uint32 timems = 0;
5522
5523 switch (GetPVPlayerState())
5524 {
5525 case PVP_STATE_PREPARED:
5526 case PVP_STATE_STARTED:
5527 {
5528 // Change the playback position immediately
5529 retval = ConvertToMillisec(aBeginPos, timems);
5530 if (retval != PVMFSuccess)
5531 {
5532 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Converting to millisec failed"));
5533 return retval;
5534 }
5535
5536 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Requested begin position is %d ms", timems));
5537
5538 retval = DoChangePlaybackPosition(aCmd.GetCmdId(), aCmd.GetContext());
5539 }
5540 break;
5541
5542 case PVP_STATE_PAUSED:
5543 {
5544 // This is for use-case: Pause - SetPlaybackRate - Resume.
5545 // In DoResume engine will call SetDataSourceDirection and then from HandleSourceNodeSetDataSourceDirection
5546 // will call UpdateCurrentBeginPosition.
5547 if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_RESUME)
5548 {
5549 // Reposition occurred during the paused state so need to change the source position first
5550 retval = DoSourceNodeQueryDataSourcePosition(aCmd.GetCmdId(), aCmd.GetContext());
5551 if (retval == PVMFSuccess)
5552 {
5553 //return Pending to indicate a node command was issued
5554 return PVMFPending;
5555 }
5556 else
5557 {
5558 //ignore failure, continue with resume sequence
5559 return PVMFSuccess;
5560 }
5561 }
5562 else
5563 {
5564 //if there's already a direction change pending, then don't
5565 //allow a reposition also
5566 if (iChangePlaybackDirectionWhenResuming)
5567 {
5568 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Direction change already pending, fail."));
5569 return PVMFErrInvalidState;
5570 }
5571
5572 // Convert the time units but flag to change playback position when resuming
5573 retval = ConvertToMillisec(aBeginPos, timems);
5574 if (retval != PVMFSuccess)
5575 {
5576 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Converting to millisec failed in paused state"));
5577 return retval;
5578 }
5579
5580 iChangePlaybackPositionWhenResuming = true;
5581
5582 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Saving requested begin position(%d ms) for resume", timems));
5583 }
5584 }
5585 break;
5586
5587 default:
5588 // Playback is stopped and start position is set so wait for playback to start
5589 break;
5590 }
5591
5592 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentBeginPosition() Out"));
5593 return retval;
5594 }
5595
DoChangePlaybackPosition(PVCommandId aCmdId,OsclAny * aCmdContext)5596 PVMFStatus PVPlayerEngine::DoChangePlaybackPosition(PVCommandId aCmdId, OsclAny* aCmdContext)
5597 {
5598 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoChangePlaybackPosition() In"));
5599
5600 // Check if the source node has position control IF or
5601 // begin position is indeterminate
5602 if (iSourceNodePBCtrlIF == NULL ||
5603 iCurrentBeginPosition.iIndeterminate ||
5604 ((iCurrentBeginPosition.iPosUnit != PVPPBPOSUNIT_MILLISEC) &&
5605 (iCurrentBeginPosition.iPlayListPosUnit != PVPPBPOSUNIT_MILLISEC)))
5606 {
5607 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoChangePlaybackPosition() Playback control IF on source node not available or invalid begin position"));
5608 return PVMFFailure;
5609 }
5610
5611 PVMFCommandId cmdid = -1;
5612
5613 if (iSeekToSyncPoint && iSyncPointSeekWindow > 0)
5614 {
5615 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryDataSourcePositionDuringPlayback);
5616
5617 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoChangePlaybackPosition() Querying source position. Position %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
5618 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoChangePlaybackPosition() Querying source position. Position %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
5619 int32 leavecode = 0;
5620
5621 // As in case of MP4 file we need to call overload function of QueryDataSourcePosition which retruns
5622 // I frame before and after instead of actaul NPT, format type will be checked here to first find if
5623 // format-type is one of the MP4 varient
5624
5625 PVMFNodeCapability nodeCapability;
5626 iSourceNode->GetCapability(nodeCapability);
5627 PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
5628 bool mpeg4FormatType = false;
5629 if (formatType != NULL)
5630 {
5631 if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
5632 {
5633 mpeg4FormatType = true;
5634 }
5635 else
5636 {
5637 mpeg4FormatType = false;
5638 }
5639 }
5640
5641 if (mpeg4FormatType)
5642 {
5643 OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT,
5644 iSeekPointBeforeTargetNPT, iSeekPointAfterTargetNPT, (OsclAny*)context, iSeekToSyncPoint));
5645 }
5646 else
5647 {
5648 OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT, iActualNPT,
5649 iSeekToSyncPoint, (OsclAny*)context));
5650 }
5651
5652 OSCL_FIRST_CATCH_ANY(leavecode,
5653 FreeEngineContext(context);
5654 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoChangePlaybackPosition() QueryDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
5655 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
5656 {
5657 return leavecode;
5658 }
5659 else
5660 {
5661 return PVMFFailure;
5662 }
5663 );
5664 }
5665 else
5666 {
5667 // Go straight to repositioning the data source
5668 PVMFStatus retval = DoSourceNodeSetDataSourcePositionDuringPlayback(aCmdId, aCmdContext);
5669 if (retval == PVMFSuccess)
5670 {
5671 return PVMFPending;
5672 }
5673 else
5674 {
5675 return retval;
5676 }
5677 }
5678
5679 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoChangePlaybackPosition() Out"));
5680
5681 return PVMFPending;
5682 }
5683
DoSourceNodeSetDataSourcePositionDuringPlayback(PVCommandId aCmdId,OsclAny * aCmdContext)5684 PVMFStatus PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback(PVCommandId aCmdId, OsclAny* aCmdContext)
5685 {
5686 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() In"));
5687
5688 // Check if the source node has position control IF
5689 if (iSourceNodePBCtrlIF == NULL)
5690 {
5691 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() No source playback control IF"));
5692 return PVMFFailure;
5693 }
5694 bool clockpausedhere = false;
5695 switch (iPlaybackPositionMode)
5696 {
5697 case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT:
5698 case PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION:
5699 break;
5700 case PVPPBPOS_MODE_NOW:
5701 default:
5702 // Pause the playback clock
5703 clockpausedhere = iPlaybackClock.Pause();
5704
5705 // Stop the playback position status timer
5706 StopPlaybackStatusTimer();
5707 break;
5708 }
5709 // Set the new position on the source node
5710 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourcePositionDuringPlayback);
5711
5712 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() Calling SetDataSourcePosition() on source node. TargetNPT %d ms, SeekToSyncPoint %d", iTargetNPT, iSeekToSyncPoint));
5713
5714 int32 leavecode = 0;
5715 if (iCurrentBeginPosition.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
5716 {
5717 iDataSourcePosParams.iActualMediaDataTS = 0;
5718 iDataSourcePosParams.iActualNPT = 0;
5719 if ((iCurrentBeginPosition.iMode == PVPPBPOS_MODE_UNKNOWN) ||
5720 (iCurrentBeginPosition.iMode == PVPPBPOS_MODE_NOW))
5721 {
5722 iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_MODE_NOW;
5723 }
5724 else if (iCurrentBeginPosition.iMode == PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT)
5725 {
5726 iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_END_OF_CURRENT_PLAY_ELEMENT;
5727 }
5728 else if (iCurrentBeginPosition.iMode == PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION)
5729 {
5730 iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_MODE_END_OF_CURRENT_PLAY_SESSION;
5731 }
5732 iDataSourcePosParams.iPlayElementIndex = iCurrentBeginPosition.iPlayElementIndex;
5733 iDataSourcePosParams.iSeekToSyncPoint = iSeekToSyncPoint;
5734 iDataSourcePosParams.iTargetNPT = iCurrentBeginPosition.iPlayListPosValue.millisec_value;
5735 iDataSourcePosParams.iStreamID = iStreamID;
5736 iDataSourcePosParams.iPlaylistUri = iCurrentBeginPosition.iPlayListUri;
5737
5738 leavecode = IssueSourceSetDataSourcePosition(true, (OsclAny*)context);
5739 if (leavecode != 0)
5740 {
5741 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
5742 FreeEngineContext(context);
5743 if (clockpausedhere)
5744 {
5745 // Resume the clock if paused in this function
5746 StartPlaybackClock();
5747 }
5748
5749 --iStreamID;
5750
5751 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
5752 {
5753 return leavecode;
5754 }
5755 else
5756 {
5757 return PVMFFailure;
5758 }
5759 }
5760 }
5761 else
5762 {
5763 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition on iSourceNodePBCtrlIF - TargetNPT=%d, SeekToSyncPoint=%d", iTargetNPT, iSeekToSyncPoint));
5764 leavecode = IssueSourceSetDataSourcePosition(false, (OsclAny*)context);
5765
5766 if (leavecode != 0)
5767 {
5768 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
5769 FreeEngineContext(context);
5770 if (clockpausedhere)
5771 {
5772 // Resume the clock if paused in this function
5773 StartPlaybackClock();
5774 }
5775 --iStreamID;
5776 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
5777 {
5778 return leavecode;
5779 }
5780 else
5781 {
5782 return PVMFFailure;
5783 }
5784 }
5785 }
5786 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePositionDuringPlayback() Out"));
5787
5788 return PVMFSuccess;
5789 }
5790
DoSinkNodeSkipMediaDataDuringPlayback(PVCommandId aCmdId,OsclAny * aCmdContext,bool aSFR)5791 PVMFStatus PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback(PVCommandId aCmdId,
5792 OsclAny* aCmdContext,
5793 bool aSFR)
5794 {
5795 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
5796 (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Tick=%d", OsclTickCount::TickCount()));
5797
5798 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() In"));
5799
5800 // Pause the playback clock
5801 bool clockpausedhere = iPlaybackClock.Pause();
5802
5803 // Tell the sink nodes to skip the unneeded media data
5804 iNumPendingNodeCmd = 0;
5805 int32 leavecode = 0;
5806
5807 // For all sink node with sync control IF, call SkipMediaData()
5808 for (uint32 i = 0; i < iDatapathList.size(); ++i)
5809 {
5810 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
5811 (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Calling SkipMediaData() on sink nodes. MediadataTS to flush to %d ms, MediadataTS to skip to %d ms", iActualMediaDataTS, iSkipMediaDataTS));
5812
5813 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
5814 (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Calling SkipMediaData() on sink nodes. MediadataTS to flush to %d ms, MediadataTS to skip to %d ms", iActualMediaDataTS, iSkipMediaDataTS));
5815
5816 if (iDatapathList[i].iDatapath &&
5817 iDatapathList[i].iEndOfDataReceived == false &&
5818 iDatapathList[i].iSinkNodeSyncCtrlIF != NULL)
5819 {
5820 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeSkipMediaDataDuringPlayback);
5821 leavecode = IssueSinkSkipMediaData(&(iDatapathList[i]), aSFR, (OsclAny*) context);
5822
5823 if (leavecode == 0)
5824 {
5825 ++iNumPendingNodeCmd;
5826 ++iNumPendingSkipCompleteEvent;
5827 ++iNumPVMFInfoStartOfDataPending;
5828 }
5829 else
5830 {
5831 FreeEngineContext(context);
5832 }
5833 }
5834 }
5835
5836 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Out"));
5837 if (iNumPendingNodeCmd > 0)
5838 {
5839 return PVMFSuccess;
5840 }
5841 else
5842 {
5843 if (clockpausedhere)
5844 {
5845 // Resume the clock if paused in this function
5846 StartPlaybackClock();
5847 }
5848
5849 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeSkipMediaDataDuringPlayback() Skip on sink nodes failed"));
5850 return PVMFFailure;
5851 }
5852 }
5853
5854
DoGetPlaybackRange(PVPlayerEngineCommand & aCmd)5855 PVMFStatus PVPlayerEngine::DoGetPlaybackRange(PVPlayerEngineCommand& aCmd)
5856 {
5857 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRange() In"));
5858
5859 if (aCmd.GetParam(0).pPlaybackpos_value == NULL ||
5860 aCmd.GetParam(1).pPlaybackpos_value == NULL)
5861 {
5862 // User did not pass in the reference to write the start and stop positions
5863 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Passed in parameter invalid."));
5864 return PVMFErrArgument;
5865 }
5866
5867 if (aCmd.GetParam(2).bool_value)
5868 {
5869 // Return the queued playback range
5870 if (iQueuedRangePresent)
5871 {
5872 *(aCmd.GetParam(0).pPlaybackpos_value) = iQueuedBeginPosition;
5873 *(aCmd.GetParam(1).pPlaybackpos_value) = iQueuedEndPosition;
5874 }
5875 else
5876 {
5877 // Queued range has not been set
5878 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Queued range not set"));
5879 return PVMFErrNotReady;
5880 }
5881 }
5882 else
5883 {
5884 PVMFStatus retval = PVMFSuccess;
5885
5886 // Return the current playback range
5887 if (iCurrentBeginPosition.iIndeterminate)
5888 {
5889 // Since indeterminate, just directly copy
5890 *(aCmd.GetParam(0).pPlaybackpos_value) = iCurrentBeginPosition;
5891 }
5892 else
5893 {
5894 retval = ConvertFromMillisec(iCurrentBeginPosition.iPosValue.millisec_value, *(aCmd.GetParam(0).pPlaybackpos_value));
5895 if (retval != PVMFSuccess)
5896 {
5897 // The conversion failed.
5898 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Conversion from millisec failed (1)"));
5899 return retval;
5900 }
5901 }
5902
5903 if (iCurrentEndPosition.iIndeterminate)
5904 {
5905 // Since indeterminate, just directly copy
5906 *(aCmd.GetParam(1).pPlaybackpos_value) = iCurrentEndPosition;
5907 }
5908 else
5909 {
5910 retval = ConvertFromMillisec(iCurrentEndPosition.iPosValue.millisec_value, *(aCmd.GetParam(1).pPlaybackpos_value));
5911 if (retval != PVMFSuccess)
5912 {
5913 // The conversion failed.
5914 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRange() Conversion from millisec failed (2)"));
5915 return retval;
5916 }
5917 }
5918 }
5919
5920 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
5921 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRange() Out"));
5922 return PVMFSuccess;
5923 }
5924
5925
DoGetCurrentPosition(PVPlayerEngineCommand & aCmd,bool aSyncCmd)5926 PVMFStatus PVPlayerEngine::DoGetCurrentPosition(PVPlayerEngineCommand& aCmd, bool aSyncCmd)
5927 {
5928 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetCurrentPosition() In"));
5929
5930 PVPPlaybackPosition* pbpos = aCmd.GetParam(0).pPlaybackpos_value;
5931
5932 if (GetPVPlayerState() == PVP_STATE_IDLE ||
5933 GetPVPlayerState() == PVP_STATE_ERROR)
5934 {
5935 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetCurrentPosition() Wrong engine state"));
5936 return PVMFErrInvalidState;
5937 }
5938
5939 if (pbpos == NULL)
5940 {
5941 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetCurrentPosition() Passed in parameter invalid."));
5942 return PVMFErrArgument;
5943 }
5944
5945 // Query playback clock for current playback position
5946 GetPlaybackClockPosition(*pbpos);
5947
5948 if (pbpos->iIndeterminate)
5949 {
5950 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetCurrentPosition() Passed in parameter invalid."));
5951 return PVMFErrArgument;
5952 }
5953
5954 if (!aSyncCmd)
5955 {
5956 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
5957 }
5958
5959 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetCurrentPosition() Out"));
5960 return PVMFSuccess;
5961 }
5962
5963
DoSetPlaybackRate(PVPlayerEngineCommand & aCmd)5964 PVMFStatus PVPlayerEngine::DoSetPlaybackRate(PVPlayerEngineCommand& aCmd)
5965 {
5966 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() In"));
5967
5968 int32 rate = aCmd.GetParam(0).int32_value;
5969 PVMFTimebase* timebase = (PVMFTimebase*)(aCmd.GetParam(1).pOsclAny_value);
5970
5971 // Split the rate into the absolute value plus the direction 1 or -1.
5972 int32 direction = 1;
5973 if (rate < 0)
5974 {
5975 direction = (-1);
5976 rate = (-rate);
5977 }
5978
5979 // Check if called in valid states.
5980 if (GetPVPlayerState() != PVP_STATE_PREPARED
5981 && GetPVPlayerState() != PVP_STATE_STARTED
5982 && GetPVPlayerState() != PVP_STATE_PAUSED)
5983 {
5984 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Wrong engine state to change rate"));
5985 return PVMFErrInvalidState;
5986 }
5987
5988 // Timebase can only be changed when prepared or paused.
5989 if (timebase != iOutsideTimebase
5990 && GetPVPlayerState() != PVP_STATE_PREPARED
5991 && GetPVPlayerState() != PVP_STATE_PAUSED)
5992 {
5993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Wrong engine state to change timebase"));
5994 return PVMFErrInvalidState;
5995 }
5996
5997 // Don't allow a direction change while paused, if there's already
5998 // a pending reposition. Engine doesn't have logic to handle both repos and
5999 // direction change during the Resume.
6000 if (direction != iPlaybackDirection
6001 && GetPVPlayerState() == PVP_STATE_PAUSED
6002 && iChangePlaybackPositionWhenResuming)
6003 {
6004 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Repos already pending-- can't change direction."));
6005 return PVMFErrInvalidState;
6006 }
6007
6008 // Switching from forward to backward really only makes sense when playing or paused,
6009 // otherwise we'll be at the end of clip. If we ever allow combined repositioning
6010 // and direction change, this restriction could be removed.
6011 if (direction != iPlaybackDirection
6012 && direction < 0
6013 && GetPVPlayerState() != PVP_STATE_STARTED
6014 && GetPVPlayerState() != PVP_STATE_PAUSED)
6015 {
6016 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Wrong engine state to go backward"));
6017 return PVMFErrInvalidState;
6018 }
6019
6020 // Validate the playback rate parameters.
6021
6022 // Rate zero is only valid with an outside timebase.
6023 if (rate == 0
6024 && timebase == NULL)
6025 {
6026 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Invalid parameter-- rate 0 with no outside timbase."));
6027 return PVMFErrArgument;
6028 }
6029
6030 // Rate must be within allowed range
6031 if (rate > 0
6032 && (rate < PVP_PBRATE_MIN || rate > PVP_PBRATE_MAX))
6033 {
6034 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Invalid parameter-- rate outside allowed range"));
6035 return PVMFErrArgument;
6036 }
6037
6038 // With an outside timebase, we can't really support rates. If -1x is input,
6039 // it means backward direction, but otherwise, rate is ignored.
6040 // So flag an error for any rate other than zero, 1x, or -1x.
6041 if (timebase != NULL
6042 && (rate != 0 && rate != 100000))
6043 {
6044 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() Invalid rate with outside timebase"));
6045 return PVMFErrInvalidState;
6046 }
6047
6048 // To do any rate change, the source node must have the playback control IF.
6049 if (rate != iPlaybackClockRate
6050 && iSourceNodePBCtrlIF == NULL)
6051 {
6052 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() iSourceNodePBCtrlIF is NULL"));
6053 return PVMFFailure;
6054 }
6055
6056 // To do any direction change, the source node must have the direction control IF.
6057 if (direction != iPlaybackDirection
6058 && iSourceNodeDirCtrlIF == NULL)
6059 {
6060 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() iSourceNodeDirCtrlIF is NULL"));
6061 return PVMFFailure;
6062 }
6063
6064 // Reset the paused-due-to-EOS flag if direction changes
6065 if (direction != iPlaybackDirection)
6066 {
6067 iPlaybackPausedDueToEndOfClip = false;
6068 //a direction change also involves an internal repositioning
6069 //so reset repos related variables and increment iStreamID
6070 ResetReposVariables(false);
6071 iStreamID++;
6072 }
6073
6074 // Save the new values. They won't be installed until they're verified
6075 iOutsideTimebase_New = timebase;
6076 iPlaybackDirection_New = direction;
6077 iPlaybackClockRate_New = rate;
6078
6079 // Start the sequence.
6080
6081 if (iPlaybackClockRate_New != iPlaybackClockRate)
6082 {
6083 // This code starts a rate change. Any direction and/or timebase change
6084 // will happen once the rate change is complete.
6085
6086 // Query the source node if the new playback rate is supported
6087 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmd.GetCmdId(), aCmd.GetContext(), PVP_CMD_SourceNodeSetDataSourceRate);
6088
6089 PVMFCommandId cmdid = -1;
6090 int32 leavecode = 0;
6091 OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->SetDataSourceRate(iSourceNodeSessionId, iPlaybackClockRate_New, iOutsideTimebase_New, (OsclAny*)context));
6092 OSCL_FIRST_CATCH_ANY(leavecode,
6093 FreeEngineContext(context);
6094 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetPlaybackRate() SetDataSourceRate on iSourceNodePBCtrlIF did a leave!"));
6095 return PVMFFailure);
6096
6097 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() Out"));
6098
6099 return PVMFSuccess;
6100 // wait for the source node callback, then HandleSourceNodeSetDataSourceRate
6101 }
6102
6103 if (iPlaybackDirection_New != iPlaybackDirection)
6104 {
6105 // Do a direction change without a rate change.
6106 PVMFStatus status = UpdateCurrentDirection(aCmd.GetCmdId(), aCmd.GetContext());
6107 switch (status)
6108 {
6109 case PVMFPending:
6110 // If we get here, engine is Prepared or Started, and we're now
6111 // waiting on source node command completion followed
6112 // by a call to HandleSourceNodeSetDataSource.
6113 // Set the return status to Success, since the caller does not expect
6114 // PVMFPending.
6115 status = PVMFSuccess;
6116 break;
6117 case PVMFSuccess:
6118 // If we get here, engine is Paused or Stopped. The SetPlaybackRate
6119 // command is done for now, but we need to set the direction when the
6120 // engine is resumed or prepared.
6121 if (iOutsideTimebase_New != iOutsideTimebase)
6122 {
6123 UpdateTimebaseAndRate();
6124 }
6125 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
6126 break;
6127 default:
6128 //failure!
6129 break;
6130 }
6131 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() Out"));
6132 return status;
6133 }
6134
6135 //If we get here it's either a timebase change, or no change at all, so
6136 //the engine command is complete.
6137 if (iOutsideTimebase_New != iOutsideTimebase)
6138 {
6139 UpdateTimebaseAndRate();
6140 }
6141
6142 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
6143
6144 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetPlaybackRate() Out"));
6145 return PVMFSuccess;
6146 }
6147
UpdateCurrentDirection(PVMFCommandId aCmdId,OsclAny * aCmdContext)6148 PVMFStatus PVPlayerEngine::UpdateCurrentDirection(PVMFCommandId aCmdId, OsclAny* aCmdContext)
6149 {
6150 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() In"));
6151
6152 // Launch a direction change sequence.
6153
6154 PVMFStatus status = PVMFFailure;
6155
6156 // Check if the source node has direction control
6157 if (!iSourceNodeDirCtrlIF)
6158 {
6159 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::UpdateCurrentDirection() Direction control IF on source node not available "));
6160 status = PVMFFailure;
6161 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Out"));
6162 return status;
6163 }
6164
6165 switch (GetPVPlayerState())
6166 {
6167 case PVP_STATE_PREPARED:
6168 case PVP_STATE_STARTED:
6169
6170 // Change the playback direction immediately
6171 status = DoSourceNodeSetDataSourceDirection(aCmdId, aCmdContext);
6172 if (status == PVMFSuccess)
6173 {
6174 //return Pending to indicate there is still a node command pending.
6175 status = PVMFPending;
6176 }
6177 else
6178 {
6179 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() DoSourceNodeSetDataSourceDirection failed."));
6180 }
6181 break;
6182
6183 case PVP_STATE_PAUSED:
6184 if (iChangePlaybackPositionWhenResuming)
6185 {
6186 //if there's already a reposition pending, don't allow
6187 //a direction change also.
6188 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Reposition already pending-- can't change direction."));
6189 status = PVMFFailure;
6190 }
6191 else
6192 {
6193 //The command will complete now-- but the direction change
6194 //won't actually occur until the engine Resume command.
6195 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Setting iChangePlaybackDirectionWhenResuming."));
6196 iChangePlaybackDirectionWhenResuming = true;
6197 status = PVMFSuccess;
6198 }
6199 break;
6200
6201 default:
6202 //not supported.
6203 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Invalid engine state"));
6204 status = PVMFErrInvalidState;
6205 break;
6206 }
6207
6208 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateCurrentDirection() Out"));
6209 return status;
6210 }
6211
DoGetPlaybackRate(PVPlayerEngineCommand & aCmd)6212 PVMFStatus PVPlayerEngine::DoGetPlaybackRate(PVPlayerEngineCommand& aCmd)
6213 {
6214 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRate() In"));
6215
6216 int32* rate = aCmd.GetParam(0).pInt32_value;
6217 PVMFTimebase** timebase = (PVMFTimebase**)(aCmd.GetParam(1).pOsclAny_value);
6218
6219 if (rate == NULL || timebase == NULL)
6220 {
6221 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRate() Passed in parameter invalid"));
6222 return PVMFErrArgument;
6223 }
6224
6225 if (GetPVPlayerState() != PVP_STATE_PREPARED &&
6226 GetPVPlayerState() != PVP_STATE_STARTED &&
6227 GetPVPlayerState() != PVP_STATE_PAUSED)
6228 {
6229 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackRate() Wrong engine state"));
6230 return PVMFErrInvalidState;
6231 }
6232
6233 // Fill in with current engine settings for playback rate
6234 *rate = iPlaybackClockRate * iPlaybackDirection;
6235 *timebase = iOutsideTimebase;
6236
6237 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
6238
6239 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackRate() Out"));
6240 return PVMFSuccess;
6241 }
6242
6243
DoGetPlaybackMinMaxRate(PVPlayerEngineCommand & aCmd)6244 PVMFStatus PVPlayerEngine::DoGetPlaybackMinMaxRate(PVPlayerEngineCommand& aCmd)
6245 {
6246 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackMinMaxRate() In"));
6247
6248 int32* minrate = aCmd.GetParam(0).pInt32_value;
6249 int32* maxrate = aCmd.GetParam(1).pInt32_value;
6250
6251 if (minrate == NULL || maxrate == NULL)
6252 {
6253 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlaybackMinMaxRate() Passed in parameter invalid"));
6254 return PVMFErrArgument;
6255 }
6256
6257 // Use hardcoded ranges for now
6258 *minrate = PVP_PBRATE_MIN;
6259 *maxrate = PVP_PBRATE_MAX;
6260
6261 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
6262
6263 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlaybackMinMaxRate() Out"));
6264 return PVMFSuccess;
6265 }
6266
6267
DoPrepare(PVPlayerEngineCommand & aCmd)6268 PVMFStatus PVPlayerEngine::DoPrepare(PVPlayerEngineCommand& aCmd)
6269 {
6270 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
6271 (0, "PVPlayerEngine::DoPrepare() Tick=%d", OsclTickCount::TickCount()));
6272
6273 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPrepare() In"));
6274
6275 if (GetPVPlayerState() == PVP_STATE_PREPARED)
6276 {
6277 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Engine already in Prepared State"));
6278 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
6279 return PVMFSuccess;
6280 }
6281
6282 if (GetPVPlayerState() != PVP_STATE_INITIALIZED)
6283 {
6284 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Wrong engine state"));
6285 return PVMFErrInvalidState;
6286 }
6287
6288 if (iState == PVP_ENGINE_STATE_PREPARING)
6289 {
6290 // Engine is already in PREPARING STATE and doing Track selection. DoPrepare will be called everytime
6291 // engine completes a stage of track selection and flips the state to _TRACK_SELECTION_1_DONE etc.
6292 // If DoPrepare called without flipping the state, that means in _PREPARING state, do nothing here
6293 // just return.
6294 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
6295 (0, "PVPlayerEngine::DoPrepare() Engine state PVP_ENGINE_STATE_PREPARING - Do Nothing"));
6296 return PVMFSuccess;
6297 }
6298
6299 PVMFStatus cmdstatus = PVMFFailure;
6300
6301 /* Engine will call DoPrepare 4 times
6302 * 1) When Engine is in PVP_ENGINE_STATE_INITIALIZED state, here engine will start the Track Selection, which
6303 * will start with Sink Nodes.
6304 * 2) After Init completes on Sink nodes Engine will be in PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE and Engine will
6305 * start creating Dec nodes and call Init on dec nodes, if needed.
6306 * 3) Init completion on Dec nodes will take Engine to PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE and Engine will
6307 * start populating the Playable List after verifying parameters of different tracks. Engine after selecting
6308 * tracks will call Reset on Sink and Dec nodes.
6309 * 4) Once Reset completes on Sink and Dec nodes, Engine will be in PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE and then
6310 * Engine will delete all the unused dec nodes.
6311 */
6312 if (iState == PVP_ENGINE_STATE_INITIALIZED)
6313 {
6314 SetEngineState(PVP_ENGINE_STATE_PREPARING);
6315
6316 // Reset the paused-due-to-EOS flag
6317 iPlaybackPausedDueToEndOfClip = false;
6318
6319 if (iDatapathList.empty() == true)
6320 {
6321 // No sink added so fail
6322 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Data sinks not added."));
6323 return PVMFErrNotReady;
6324 }
6325
6326 // Query cap-config based on available engine datapaths
6327 cmdstatus = DoSinkNodeQueryCapConfigIF(aCmd.GetCmdId(), aCmd.GetContext());
6328 if (cmdstatus != PVMFSuccess)
6329 {
6330 bool ehPending = CheckForPendingErrorHandlingCmd();
6331 if (ehPending)
6332 {
6333 // there should be no error handling queued.
6334 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
6335 return PVMFPending;
6336 }
6337 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSinkNodeQueryCapConfigIF: failed, Add EH command"));
6338 iCommandCompleteStatusInErrorHandling = cmdstatus;
6339 iCommandCompleteErrMsgInErrorHandling = NULL;
6340 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
6341 return PVMFPending;
6342 }
6343 }
6344 else if (iState == PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE)
6345 {
6346 SetEngineState(PVP_ENGINE_STATE_PREPARING);
6347
6348 // Now check for the tracks which can be played only using the Sink nodes, that means no Decoder node needed.
6349 cmdstatus = DoSinkNodeTrackSelection(aCmd.GetCmdId(), aCmd.GetContext());
6350 if (cmdstatus != PVMFSuccess)
6351 {
6352 bool ehPending = CheckForPendingErrorHandlingCmd();
6353 if (ehPending)
6354 {
6355 // there should be no error handling queued.
6356 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
6357 return PVMFPending;
6358 }
6359 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSinkNodeTrackSelection: failed, Add EH command"));
6360 iCommandCompleteStatusInErrorHandling = cmdstatus;
6361 iCommandCompleteErrMsgInErrorHandling = NULL;
6362 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
6363 return PVMFPending;
6364 }
6365
6366 // For the tracks which cannot be played by Sink nodes only, we need to instantiate decoder nodes.
6367 // Create Decoder nodes and query for the cap and config IF here.
6368 cmdstatus = DoDecNodeQueryCapConfigIF(aCmd.GetCmdId(), aCmd.GetContext());
6369 if (cmdstatus != PVMFSuccess)
6370 {
6371 bool ehPending = CheckForPendingErrorHandlingCmd();
6372 if (ehPending)
6373 {
6374 // there should be no error handling queued.
6375 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
6376 return PVMFPending;
6377 }
6378 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoDecNodeQueryCapConfigIF: failed, Add EH command"));
6379 iCommandCompleteStatusInErrorHandling = cmdstatus;
6380 iCommandCompleteErrMsgInErrorHandling = NULL;
6381 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
6382 return PVMFPending;
6383 }
6384 }
6385 else if (iState == PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE)
6386 {
6387 SetEngineState(PVP_ENGINE_STATE_PREPARING);
6388
6389 cmdstatus = DoSourceNodeTrackSelection(aCmd.GetCmdId(), aCmd.GetContext());
6390 if (cmdstatus != PVMFSuccess)
6391 {
6392 bool ehPending = CheckForPendingErrorHandlingCmd();
6393 if (ehPending)
6394 {
6395 // there should be no error handling queued.
6396 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
6397 return PVMFPending;
6398 }
6399 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSourceNodeTrackSelection: failed, Add EH command"));
6400 iCommandCompleteStatusInErrorHandling = cmdstatus;
6401 iCommandCompleteErrMsgInErrorHandling = NULL;
6402 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
6403 return PVMFPending;
6404 }
6405 // Reset all the sink and decoder nodes.
6406 cmdstatus = DoSinkNodeDecNodeReset(aCmd.GetCmdId(), aCmd.GetContext());
6407 if (cmdstatus != PVMFSuccess)
6408 {
6409 bool ehPending = CheckForPendingErrorHandlingCmd();
6410 if (ehPending)
6411 {
6412 // there should be no error handling queued.
6413 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
6414 return PVMFPending;
6415 }
6416 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoSinkNodeDecNodeReset: failed, Add EH command"));
6417 iCommandCompleteStatusInErrorHandling = cmdstatus;
6418 iCommandCompleteErrMsgInErrorHandling = NULL;
6419 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
6420 return PVMFPending;
6421 }
6422 }
6423 else if (iState == PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE)
6424 {
6425 SetEngineState(PVP_ENGINE_STATE_PREPARING);
6426
6427 cmdstatus = DoSinkDecCleanupSourcePrepare(aCmd.GetCmdId(), aCmd.GetContext());
6428 if (cmdstatus != PVMFSuccess)
6429 {
6430 bool ehPending = CheckForPendingErrorHandlingCmd();
6431 if (ehPending)
6432 {
6433 // there should be no error handling queued.
6434 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() Already EH pending, should never happen"));
6435 return PVMFPending;
6436 }
6437 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPrepare() DoDecNodeCleanup: failed, Add EH command"));
6438 iCommandCompleteStatusInErrorHandling = cmdstatus;
6439 iCommandCompleteErrMsgInErrorHandling = NULL;
6440 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
6441 return PVMFPending;
6442 }
6443 }
6444
6445 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPrepare() Out"));
6446 return PVMFSuccess;
6447 }
6448
DoSinkNodeQueryCapConfigIF(PVCommandId aCmdId,OsclAny * aCmdContext)6449 PVMFStatus PVPlayerEngine::DoSinkNodeQueryCapConfigIF(PVCommandId aCmdId, OsclAny* aCmdContext)
6450 {
6451 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() In"));
6452
6453 if (iSourceNodeTrackSelIF == NULL)
6454 {
6455 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Source node track sel IF not available. Asserting"));
6456 return PVMFFailure;
6457 }
6458
6459 uint32 i = 0;
6460 int32 leavecode = 0;
6461 uint32 numTracks = 0;
6462 PVPlayerEngineContext* context = NULL;
6463 PVMFCommandId cmdid = -1;
6464 iNumPendingNodeCmd = 0;
6465
6466 if (iSourceNodeTrackSelIF->GetMediaPresentationInfo(iSourcePresInfoList) != PVMFSuccess)
6467 {
6468 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() GetMediaPresentationInfo() call on source node failed"));
6469 return PVMFFailure;
6470 }
6471
6472 numTracks = iSourcePresInfoList.getNumTracks();
6473 iTrackSelectionList.reserve(numTracks);
6474
6475 for (i = 0; i < numTracks; i++)
6476 {
6477 // Create the track selection list, which will store a set of sink and dec node (if needed) for each track.
6478 PVPlayerEngineTrackSelection trackSelection;
6479
6480 PVMFTrackInfo* trackInfo = iSourcePresInfoList.getTrackInfo(i);
6481 trackSelection.iTsTrackID = trackInfo->getTrackID();
6482
6483 iTrackSelectionList.push_back(trackSelection);
6484 }
6485
6486 for (i = 0; i < iDatapathList.size(); ++i)
6487 {
6488 // Destroy the track info if present
6489 if (iDatapathList[i].iTrackInfo)
6490 {
6491 OSCL_DELETE(iDatapathList[i].iTrackInfo);
6492 iDatapathList[i].iTrackInfo = NULL;
6493 }
6494
6495 if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
6496 {
6497 // Create file output node for sink
6498 leavecode = 0;
6499 OSCL_TRY(leavecode, iDatapathList[i].iSinkNode = PVFileOutputNodeFactory::CreateFileOutput());
6500 OSCL_FIRST_CATCH_ANY(leavecode,
6501 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Creation of file output node did a leave!"));
6502 return PVMFErrNoMemory);
6503 }
6504 else if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_SINKNODE)
6505 {
6506 // Use the specified output node for sink node
6507 iDatapathList[i].iSinkNode = iDatapathList[i].iDataSink->GetDataSinkNodeInterface();
6508 if (iDatapathList[i].iSinkNode == NULL)
6509 {
6510 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Passed in sink node is NULL"));
6511 return PVMFFailure;
6512 }
6513 }
6514 else
6515 {
6516 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Unsupported player data sink type"));
6517 return PVMFErrNotSupported;
6518 }
6519
6520 if (iDatapathList[i].iSinkNode->ThreadLogon() != PVMFSuccess)
6521 {
6522 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() ThreadLogon() on passed-in sink node failed"));
6523 OSCL_ASSERT(false);
6524 return PVMFFailure;
6525 }
6526
6527 PVMFNodeSessionInfo nodesessioninfo(this, this, (OsclAny*)iDatapathList[i].iSinkNode, this, (OsclAny*)iDatapathList[i].iSinkNode);
6528 iDatapathList[i].iSinkNodeSessionId = iDatapathList[i].iSinkNode->Connect(nodesessioninfo);
6529
6530 // Query for Cap-Config IF
6531 context = AllocateEngineContext(&iDatapathList[i], iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeQueryCapConfigIF);
6532
6533 PVUuid capconfiguuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID;
6534 cmdid = -1;
6535 leavecode = 0;
6536 iDatapathList[i].iSinkNodePVInterfaceCapConfig = NULL;
6537 leavecode = IssueQueryInterface(iDatapathList[i].iSinkNode, iDatapathList[i].iSinkNodeSessionId, capconfiguuid, iDatapathList[i].iSinkNodePVInterfaceCapConfig, (OsclAny*)context, cmdid);
6538 if (leavecode != 0 || cmdid == -1)
6539 {
6540 iDatapathList[i].iSinkNodePVInterfaceCapConfig = NULL;
6541 FreeEngineContext(context);
6542 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() QueryInterface on sink node for cap-config IF did a leave!"));
6543 return PVMFFailure;
6544 }
6545 else
6546 {
6547 ++iNumPendingNodeCmd;
6548 }
6549 }
6550
6551 if (iNumPendingNodeCmd <= 0)
6552 {
6553 // NumPendingNodeCmd less than or equal to zero means that none of the Sink nodes support Cap-Config interface, which means that these
6554 // sinks cannot be used for playing the content. Return PVMFErrNotSupported from here which will take engine into Error handling and will fail
6555 // Prepare command.
6556 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Out No pending QueryInterface() on sink node"));
6557 return PVMFErrNotSupported;
6558 }
6559
6560 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryCapConfigIF() Out"));
6561 return PVMFSuccess;
6562 }
6563
DoSinkNodeInit(PVCommandId aCmdId,OsclAny * aCmdContext)6564 PVMFStatus PVPlayerEngine::DoSinkNodeInit(PVCommandId aCmdId, OsclAny* aCmdContext)
6565 {
6566 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
6567 (0, "PVPlayerEngine::DoSinkNodeInit() Tick=%d", OsclTickCount::TickCount()));
6568
6569 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeInit() In"));
6570
6571 iNumPendingNodeCmd = 0;
6572 PVMFCommandId cmdid = -1;
6573 int32 leavecode = 0;
6574
6575 for (uint32 i = 0; i < iDatapathList.size(); ++i)
6576 {
6577 if (iDatapathList[i].iSinkNode != NULL)
6578 {
6579 // Call Init() on the sink node
6580 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeInit);
6581
6582 leavecode = IssueSinkNodeInit(&(iDatapathList[i]), (OsclAny*) context, cmdid);
6583
6584 if (cmdid != -1 && leavecode == 0)
6585 {
6586 ++iNumPendingNodeCmd;
6587 }
6588 else
6589 {
6590 FreeEngineContext(context);
6591 return PVMFFailure;
6592 }
6593 }
6594 }
6595
6596 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeInit() Out"));
6597 return PVMFSuccess;
6598 }
6599
DoSinkNodeTrackSelection(PVCommandId aCmdId,OsclAny * aCmdContext)6600 PVMFStatus PVPlayerEngine::DoSinkNodeTrackSelection(PVCommandId aCmdId, OsclAny* aCmdContext)
6601 {
6602 OSCL_UNUSED_ARG(aCmdId);
6603 OSCL_UNUSED_ARG(aCmdContext);
6604 // For a track to be playable only by sink node, the Sink node should support the Format Type and Format Specific Info
6605 // for the track. If any of the 2 variables are not supported by the sink node, the track needs to have a decoder which
6606 // will be created in next stage of track selection. If Sink node supports both the above variables for a particular
6607 // track, the track will make to the Playable list without any decoder node.
6608 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeTrackSelection() In"));
6609
6610 PVMFStatus status = PVMFFailure;
6611
6612 PvmiKvp kvpFormatType;
6613 PvmiKvp kvpFSI;
6614
6615 OSCL_StackString<64> iKVPFormatType = _STRLIT_CHAR(PVMF_FORMAT_TYPE_VALUE_KEY);
6616
6617 const char* aFormatValType = PVMF_FORMAT_SPECIFIC_INFO_KEY;
6618
6619 OsclMemAllocator alloc;
6620
6621 kvpFormatType.key = NULL;
6622 kvpFSI.key = NULL;
6623
6624 kvpFormatType.key = iKVPFormatType.get_str();
6625
6626 kvpFSI.length = oscl_strlen(aFormatValType) + 1; // +1 for \0
6627 kvpFSI.key = (PvmiKeyType)alloc.ALLOCATE(kvpFSI.length);
6628 if (kvpFSI.key == NULL)
6629 {
6630 return PVMFErrNoMemory;
6631 }
6632 oscl_strncpy(kvpFSI.key, aFormatValType, kvpFSI.length);
6633
6634 for (uint32 i = 0; i < iDatapathList.size(); i++)
6635 {
6636 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
6637 {
6638 for (uint32 j = 0; j < iSourcePresInfoList.getNumTracks(); j++)
6639 {
6640 // if any track is already been added to the playlist then no need to check with the next Datapath
6641 // go onto the next track
6642 if (!iTrackSelectionList[j].iTsTrackValidForPlayableList)
6643 {
6644 OsclRefCounterMemFrag aConfig;
6645 PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(j);
6646 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeTrackSelection() Check format type for %s", currTrack->getTrackMimeType().get_cstr()));
6647
6648 kvpFormatType.value.pChar_value = currTrack->getTrackMimeType().get_str();
6649
6650 // Check for the format type of the track first. If Supported move to Format specific info, if not
6651 // move on to the next track.
6652
6653 status = iDatapathList[i].iSinkNodeCapConfigIF->verifyParametersSync(NULL, &kvpFormatType, 1);
6654
6655 if (status == PVMFSuccess)
6656 {
6657 // go ahead and check for Format specific info
6658 aConfig = currTrack->getTrackConfigInfo();
6659 kvpFSI.value.key_specific_value = (OsclAny*)(aConfig.getMemFragPtr());
6660 kvpFSI.capacity = aConfig.getMemFragSize();
6661
6662 status = iDatapathList[i].iSinkNodeCapConfigIF->verifyParametersSync(NULL, &kvpFSI, 1);
6663
6664 if (status == PVMFSuccess)
6665 {
6666 // This track can be played just using the Sink nodes we need not have decoders for this track
6667 // Set the boolean iTsTrackValidForPlayableList to true in the TrackSelectionList.
6668 // Check the boolean iTsTrackValidForPlayableList before creating the decoder nodes, if
6669 // already set no need for decoders.
6670 iTrackSelectionList[j].iTsSinkNode = iDatapathList[i].iSinkNode;
6671 iTrackSelectionList[j].iTsSinkNodeCapConfigIF = iDatapathList[i].iSinkNodeCapConfigIF;
6672 iTrackSelectionList[j].iTsTrackValidForPlayableList = true;
6673 }
6674 }
6675 }
6676 // if any of the above verifyParameterSync returns a failure, just move onto the next track.
6677 }
6678 }
6679 }
6680
6681 alloc.deallocate((OsclAny*)(kvpFSI.key));
6682 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeTrackSelection() Out"));
6683 return PVMFSuccess;
6684 }
6685
DoDecNodeQueryCapConfigIF(PVCommandId aCmdId,OsclAny * aCmdContext)6686 PVMFStatus PVPlayerEngine::DoDecNodeQueryCapConfigIF(PVCommandId aCmdId, OsclAny* aCmdContext)
6687 {
6688 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() In"));
6689
6690 int32 leavecode = 0;
6691 PVPlayerEngineContext* context = NULL;
6692 PVMFCommandId cmdid = -1;
6693
6694 PVMFFormatType iSrcFormat = 0;
6695 PVMFFormatType iSinkFormat = 0;
6696
6697 iNumPendingNodeCmd = 0;
6698
6699 uint32 numTracks = iSourcePresInfoList.getNumTracks();
6700
6701 for (uint32 i = 0; i < numTracks; i++)
6702 {
6703 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Check the track"));
6704 for (uint32 j = 0; j < iDatapathList.size(); j++)
6705 {
6706 // Start creating decoder nodes for tracks which cannot be played with Sink nodes alone.
6707 // It is also possible that there can be similar tracks with same mime strings but with
6708 // different config parameters which share the same decoder node. For these similar tracks
6709 // engine should not create decoder nodes again, it should use the same decoder node instance.
6710 if (iTrackSelectionList[i].iTsDecNode == NULL && !iTrackSelectionList[i].iTsTrackValidForPlayableList)
6711 {
6712 PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
6713 iSrcFormat = currTrack->getTrackMimeType().get_str();
6714
6715 //Try to get supported formats from the media I/O component.
6716 PvmiKvp* kvp = NULL;
6717 int numParams = 0;
6718 PVMFStatus status = iDatapathList[j].iSinkNodeCapConfigIF->getParametersSync(NULL, (char*)INPUT_FORMATS_CAP_QUERY, kvp, numParams, NULL);
6719 if (status == PVMFSuccess)
6720 {
6721 for (int k = 0; k < numParams; k++)
6722 {
6723 iSinkFormat = kvp[k].value.pChar_value;
6724
6725 Oscl_Vector<PVUuid, OsclMemAllocator> foundUuids;
6726 // Query the player node registry for the required decoder node
6727 if (iPlayerNodeRegistry.QueryRegistry(iSrcFormat, iSinkFormat, foundUuids) == PVMFSuccess)
6728 {
6729 if (!foundUuids.empty())
6730 {
6731 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Node found for %s, sink %s", currTrack->getTrackMimeType().get_str(), iSinkFormat.getMIMEStrPtr()));
6732 iTrackSelectionList[i].iTsDecNode = iPlayerNodeRegistry.CreateNode(foundUuids[0]);
6733
6734 if (iTrackSelectionList[i].iTsDecNode != NULL)
6735 {
6736 iNodeUuids.push_back(PVPlayerEngineUuidNodeMapping(foundUuids[0], iTrackSelectionList[i].iTsDecNode));
6737
6738 if (iTrackSelectionList[i].iTsDecNode->ThreadLogon() != PVMFSuccess)
6739 {
6740 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() ThreadLogon() on dec node failed"));
6741 OSCL_ASSERT(false);
6742 }
6743
6744 PVMFNodeSessionInfo nodesessioninfo(this, this, (OsclAny*)iTrackSelectionList[i].iTsDecNode, this, (OsclAny*)iTrackSelectionList[i].iTsDecNode);
6745 iTrackSelectionList[i].iTsDecNodeSessionId = iTrackSelectionList[i].iTsDecNode->Connect(nodesessioninfo);
6746
6747 // Query for CapConfig IF
6748 context = AllocateEngineContext(NULL, iTrackSelectionList[i].iTsDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_DecNodeQueryCapConfigIF);
6749
6750 PVUuid capconfiguuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID;
6751 cmdid = -1;
6752 iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
6753 leavecode = IssueQueryInterface(iTrackSelectionList[i].iTsDecNode, iTrackSelectionList[i].iTsDecNodeSessionId, capconfiguuid, iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig, (OsclAny*)context, cmdid);
6754 if (cmdid == -1 || leavecode != 0)
6755 {
6756 iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
6757 FreeEngineContext(context);
6758 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() QueryInterface on dec node for cap-config IF did a leave!"));
6759 }
6760 else
6761 {
6762 ++iNumPendingNodeCmd;
6763 }
6764
6765 // A decoder is found in the registry and succesfully created for the particular set of track and datapath.
6766 // Set the sink nodes and its cap and config IF for the track in trackSelectionList
6767 iTrackSelectionList[i].iTsSinkNode = iDatapathList[j].iSinkNode;
6768 iTrackSelectionList[i].iTsSinkNodeCapConfigIF = iDatapathList[j].iSinkNodeCapConfigIF;
6769 iTrackSelectionList[i].iTsSinkNodeSessionId = iDatapathList[j].iSinkNodeSessionId;
6770
6771 // Set the sink format for the datapath.
6772 iDatapathList[j].iSinkFormat = iSinkFormat;
6773
6774 // Valid decoder node set in TrackSelectionList. Scan the TrackSelectionList further and if
6775 // any similar MIME track is there just use the same decoder and the same sink nodes.
6776 for (uint32 s = i + 1; s < numTracks; s++)
6777 {
6778 PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(s);
6779 if (!(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())))
6780 {
6781 iTrackSelectionList[s].iTsSinkNode = iTrackSelectionList[i].iTsSinkNode;
6782 iTrackSelectionList[s].iTsSinkNodeCapConfigIF = iTrackSelectionList[i].iTsSinkNodeCapConfigIF;
6783 iTrackSelectionList[s].iTsSinkNodeSessionId = iTrackSelectionList[i].iTsSinkNodeSessionId;
6784
6785 iTrackSelectionList[s].iTsDecNode = iTrackSelectionList[i].iTsDecNode;
6786 iTrackSelectionList[s].iTsDecNodeSessionId = iTrackSelectionList[i].iTsDecNodeSessionId;
6787 }
6788 }
6789
6790 k = numParams;
6791 }
6792 else
6793 {
6794 // Create node on decoder failed, check with the next sink format
6795 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Dec node creation failed"));
6796 }
6797 }
6798 else
6799 {
6800 // No matching node found with the given Sinkformat, check with the next Sink Format
6801 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() No matching decoder node found"));
6802 }
6803 }
6804 else
6805 {
6806 // Registry query failed with the given Sinkformat, check with the next Sink Format.
6807 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Registry query for dec node failed"));
6808 }
6809 }
6810 iDatapathList[j].iSinkNodeCapConfigIF->releaseParameters(0, kvp, numParams);
6811 }
6812 else
6813 {
6814 // getParamterSync on MIO node to get the supported formats by MIO failed
6815 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() getParamterSync on MIO node to get the supported formats by MIO failed"));
6816 }
6817 }
6818 }
6819 }
6820
6821 if (iNumPendingNodeCmd == 0)
6822 {
6823 // no decoder nodes are needed, go ahead for track selection logic
6824 SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE);
6825 RunIfNotReady();
6826 }
6827 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryCapConfigIF() Out"));
6828 return PVMFSuccess;
6829 }
6830
DoDecNodeInit(PVCommandId aCmdId,OsclAny * aCmdContext)6831 PVMFStatus PVPlayerEngine::DoDecNodeInit(PVCommandId aCmdId, OsclAny* aCmdContext)
6832 {
6833 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
6834 (0, "PVPlayerEngine::DoDecNodeInit() Tick=%d", OsclTickCount::TickCount()));
6835
6836 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeInit() In"));
6837
6838 iNumPendingNodeCmd = 0;
6839 PVMFCommandId cmdid = -1;
6840 int32 leavecode = 0;
6841
6842 for (uint32 i = 0; i < iTrackSelectionList.size(); ++i)
6843 {
6844 if (iTrackSelectionList[i].iTsDecNode != NULL)
6845 {
6846 // Call Init() on the dec node
6847 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iTrackSelectionList[i].iTsDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_DecNodeInit);
6848
6849 leavecode = IssueDecNodeInit(iTrackSelectionList[i].iTsDecNode, iTrackSelectionList[i].iTsDecNodeSessionId, (OsclAny*) context, cmdid);
6850
6851 if (cmdid != -1 && leavecode == 0)
6852 {
6853 ++iNumPendingNodeCmd;
6854 }
6855 else
6856 {
6857 FreeEngineContext(context);
6858 return PVMFFailure;
6859 }
6860 }
6861 }
6862
6863 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeInit() Out"));
6864 return PVMFSuccess;
6865 }
6866
DoSourceNodeTrackSelection(PVCommandId,OsclAny *)6867 PVMFStatus PVPlayerEngine::DoSourceNodeTrackSelection(PVCommandId /*aCmdId*/, OsclAny* /*aCmdContext*/)
6868 {
6869 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() In"));
6870
6871 if (iSourceNodeTrackSelIF == NULL)
6872 {
6873 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() Source node track sel IF not available."));
6874 return PVMFFailure;
6875 }
6876
6877 //populate playable list first
6878 PVMFStatus retval = DoTrackSelection(true, false);
6879 if (retval != PVMFSuccess)
6880 {
6881 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() DoTrackSelection - Populating playable list Failed"));
6882 return retval;
6883 }
6884
6885 bool usepreferencelist = false;
6886 if (iTrackSelectionHelper != NULL)
6887 {
6888 PVMFMediaPresentationInfo localList;
6889 iPreferenceList.Reset();
6890 localList.setPresentationType(iPlayableList.getPresentationType());
6891 localList.setSeekableFlag(iPlayableList.IsSeekable());
6892 localList.SetDurationAvailable(iPlayableList.IsDurationAvailable());
6893 localList.setDurationValue(iPlayableList.getDurationValue());
6894 localList.setDurationTimeScale(iPlayableList.getDurationTimeScale());
6895 //if track selection helper is present, it means that
6896 //user of engine wants to provide inputs
6897 //the reason we use a local list instead of iPreferenceList is
6898 //due to memory consideration. This call to "SelectTracks" goes
6899 //to the app and the app allocates memory to populate the local list
6900 //This memory needs to be released right away. So we make a copy
6901 //and release the memory for local list.
6902 PVMFStatus status =
6903 iTrackSelectionHelper->SelectTracks(iPlayableList, localList);
6904 if ((status == PVMFSuccess) &&
6905 (localList.getNumTracks() != 0))
6906 {
6907 usepreferencelist = true;
6908 iPreferenceList = localList;
6909 }
6910 //release memory now that we have made a copy
6911 iTrackSelectionHelper->ReleasePreferenceList(localList);
6912 //else user made no choice, use playable list
6913 }
6914
6915 retval = DoTrackSelection(false, usepreferencelist);
6916 if (retval != PVMFSuccess)
6917 {
6918 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() DoTrackSelection - TrackSelection Failed"));
6919 return retval;
6920 }
6921
6922 uint32 i = 0;
6923
6924 // Create a selected track list
6925 PVMFMediaPresentationInfo selectedtracks;
6926 for (i = 0; i < iDatapathList.size(); ++i)
6927 {
6928 if (iDatapathList[i].iTrackInfo != NULL)
6929 {
6930 selectedtracks.addTrackInfo(*(iDatapathList[i].iTrackInfo));
6931 }
6932 }
6933
6934 // Check that at least one track was selected
6935 if (selectedtracks.getNumTracks() == 0)
6936 {
6937 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() No tracks were selected"));
6938 // @TODO Provide a more specific error info
6939 return PVMFErrResourceConfiguration;
6940 }
6941
6942 // Select in source node
6943 retval = iSourceNodeTrackSelIF->SelectTracks(selectedtracks);
6944 if (retval != PVMFSuccess)
6945 {
6946 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() SelectTracks() on source node failed"));
6947 return retval;
6948 }
6949
6950 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeTrackSelection() Out"));
6951 return retval;
6952 }
6953
DoTrackSelection(bool oPopulatePlayableListOnly,bool oUsePreferenceList)6954 PVMFStatus PVPlayerEngine::DoTrackSelection(bool oPopulatePlayableListOnly, bool oUsePreferenceList)
6955 {
6956 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoTrackSelection() In"));
6957
6958 if (iSourceNodeTrackSelIF == NULL)
6959 {
6960 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoTrackSelection() Source node track sel IF not available."));
6961 return PVMFFailure;
6962 }
6963
6964 PVMFMediaPresentationInfo sourcepresinfo;
6965 if (oPopulatePlayableListOnly)
6966 {
6967 // use already saved presentation info list from source node
6968 sourcepresinfo = iSourcePresInfoList;
6969
6970 iPlayableList.Reset();
6971
6972 iPlayableList.setPresentationType(iSourcePresInfoList.getPresentationType());
6973 iPlayableList.setSeekableFlag(iSourcePresInfoList.IsSeekable());
6974 iPlayableList.SetDurationAvailable(iSourcePresInfoList.IsDurationAvailable());
6975 iPlayableList.setDurationValue(iSourcePresInfoList.getDurationValue());
6976 iPlayableList.setDurationTimeScale(iSourcePresInfoList.getDurationTimeScale());
6977 }
6978 else
6979 {
6980 if (oUsePreferenceList)
6981 {
6982 //perform track selection based on playable list
6983 sourcepresinfo = iPreferenceList;
6984 }
6985 else
6986 {
6987 //perform track selection based on playable list
6988 sourcepresinfo = iPlayableList;
6989 }
6990 }
6991
6992 PVMFStatus retVal = PVMFSuccess;
6993 uint32 i = 0;
6994 uint32 k = 0;
6995
6996 if (oPopulatePlayableListOnly)
6997 {
6998 for (i = 0; i < iDatapathList.size(); i++)
6999 {
7000 // Destroy the track info if present
7001 if (iDatapathList[i].iTrackInfo)
7002 {
7003 OSCL_DELETE(iDatapathList[i].iTrackInfo);
7004 iDatapathList[i].iTrackInfo = NULL;
7005 }
7006 }
7007
7008 for (i = 0; i < sourcepresinfo.getNumTracks(); i++)
7009 {
7010 PVMFStatus checkcodec = PVMFFailure;
7011 int32 trackId = -1;
7012
7013 // Go through each track, check codec type, and save the track info
7014 PVMFTrackInfo* curtrack = sourcepresinfo.getTrackInfo(i);
7015 trackId = curtrack->getTrackID();
7016
7017 // check if this track can be directly pushed in playable list. This will be the case where decoder node is not needed
7018 // and Sink node supports the format and format specific info. OR
7019 // The track is a text track.
7020
7021 if (iTrackSelectionList[i].iTsDecNode == NULL)
7022 {
7023 // check if it is a valid track or not, decoder node can be NULL only in 2 cases
7024 // 1) Track can be played without decoder nodes, here iTsTrackValidForPlayableList should be true OR track is TEXT track
7025 // 2) If the track is not valid at all, if this is the case, move onto next track.
7026
7027 if (iTrackSelectionList[i].iTsTrackValidForPlayableList ||
7028 (pv_mime_strcmp(curtrack->getTrackMimeType().get_str(), PVMF_MIME_3GPP_TIMEDTEXT)) == 0)
7029 {
7030 // this can make directly to the Playable list, since it satisfies condition# 1 above.
7031 iPlayableList.addTrackInfo(*curtrack);
7032 iTrackSelectionList[i].iTsTrackValidForPlayableList = false;
7033 checkcodec = PVMFSuccess;
7034 }
7035 }
7036 else
7037 {
7038 // if sink node alone does not support this track verify its parameters.
7039 retVal = DoVerifyTrackInfo(iTrackSelectionList[i], curtrack, checkcodec);
7040 if (retVal != PVMFSuccess)
7041 return retVal;
7042
7043 if (checkcodec == PVMFSuccess)
7044 {
7045 //add it to playable list
7046 iPlayableList.addTrackInfo(*curtrack);
7047 }
7048 }
7049
7050 if (checkcodec != PVMFSuccess && trackId >= 0)
7051 {
7052 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoTrackSelection() Bad track config for TrackId=%d", trackId));
7053 SendInformationalEvent(PVMFInfoTrackDisable, NULL, (OsclAny*)trackId, NULL, 0);
7054 }
7055 }
7056 }
7057 else
7058 {
7059 for (i = 0; i < sourcepresinfo.getNumTracks(); i++)
7060 {
7061 PVMFTrackInfo* curtrack = sourcepresinfo.getTrackInfo(i);
7062
7063 for (k = 0; k < iTrackSelectionList.size(); k++)
7064 {
7065 // check which track is selected by comparing the TrackId
7066 int32 trackId = curtrack->getTrackID();
7067 if (trackId == iTrackSelectionList[k].iTsTrackID)
7068 {
7069 for (uint32 j = 0; j < iDatapathList.size(); j++)
7070 {
7071 // if a track has already been added to the datapath, move onto the next datapath.
7072 if (!iDatapathList[j].iTrackInfo)
7073 {
7074 // check for the corresponding datapath to the track
7075 if (iDatapathList[j].iSinkNode == iTrackSelectionList[k].iTsSinkNode)
7076 {
7077 if (curtrack->DoesTrackHaveDependency() == true)
7078 {
7079 // Track has dependency, move onto next track
7080 j = iDatapathList.size();
7081 k = iTrackSelectionList.size();
7082 }
7083 else
7084 {
7085 // The track has been added to the final list, this means that this track is valid
7086 // and will make to DatapathList and all other video decoders will be destroyed.
7087 iDatapathList[j].iTrackInfo = OSCL_NEW(PVMFTrackInfo, (*curtrack));
7088
7089 // set the decoder node, its session id and decoder cap&config IF in the Datapath, since the track is the
7090 // selected one.
7091 if (iTrackSelectionList[k].iTsDecNode)
7092 {
7093 iDatapathList[j].iDecNode = iTrackSelectionList[k].iTsDecNode;
7094 iDatapathList[j].iDecNodeSessionId = iTrackSelectionList[k].iTsDecNodeSessionId;
7095 iDatapathList[j].iDecNodeCapConfigIF = iTrackSelectionList[k].iTsDecNodeCapConfigIF;
7096 }
7097
7098 iTrackSelectionList[k].iTsSinkNode = NULL;
7099 iTrackSelectionList[k].iTsSinkNodeSessionId = 0;
7100 iTrackSelectionList[k].iTsSinkNodeCapConfigIF = NULL;
7101
7102 iTrackSelectionList[k].iTsDecNode = NULL;
7103 iTrackSelectionList[k].iTsDecNodeSessionId = 0;
7104 iTrackSelectionList[k].iTsDecNodeCapConfigIF = NULL;
7105 iTrackSelectionList[k].iTsDecNodePVInterfaceCapConfig = NULL;
7106
7107 iTrackSelectionList[k].iTsTrackID = -1;
7108 iTrackSelectionList[k].iTsTrackValidForPlayableList = false;
7109 }
7110 j = iDatapathList.size();
7111 }
7112 // Datapath sinknode does not match, check the next datapath for the track
7113 }
7114 // a track has already been assigned for the datapath, check next datapath for the track
7115 }
7116 k = iTrackSelectionList.size();
7117 }
7118 // The trackId of the track does not match with the track in the List, check the next track.
7119 }
7120 }
7121
7122 // Go through the track selection list and set similar decoder nodes to NULL. There should be only 1 entry
7123 // of a decoder node either in DatapathList (this will be for the final playable track) or in
7124 // TrackSelectionList which will be for tracks which will not be used for playback.
7125 for (i = 0; i < iTrackSelectionList.size(); i++)
7126 {
7127 PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
7128 for (uint32 j = i + 1; j < iTrackSelectionList.size(); j++)
7129 {
7130 PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(j);
7131 if (!(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())))
7132 {
7133 iTrackSelectionList[j].iTsDecNode = NULL;
7134 iTrackSelectionList[j].iTsDecNodeSessionId = 0;
7135 iTrackSelectionList[j].iTsDecNodeCapConfigIF = NULL;
7136 }
7137 }
7138 }
7139
7140 // now go through whole TrackSelectionList and look for similar sink and decoder nodes
7141 // to the track selected i.e. added to datapath, set all sink and decoder nodes to NULL for the track selected
7142 for (k = 0; k < iDatapathList.size(); k++)
7143 {
7144 for (uint32 s = 0; s < iTrackSelectionList.size(); s++)
7145 {
7146 if ((iDatapathList[k].iSinkNode == iTrackSelectionList[s].iTsSinkNode))
7147 {
7148 iTrackSelectionList[s].iTsSinkNode = NULL;
7149 iTrackSelectionList[s].iTsSinkNodeSessionId = 0;
7150 iTrackSelectionList[s].iTsSinkNodeCapConfigIF = NULL;
7151 }
7152
7153 if ((iDatapathList[k].iDecNode != NULL) &&
7154 (iDatapathList[k].iDecNode == iTrackSelectionList[s].iTsDecNode))
7155 {
7156 iTrackSelectionList[s].iTsDecNode = NULL;
7157 iTrackSelectionList[s].iTsDecNodeSessionId = 0;
7158 iTrackSelectionList[s].iTsDecNodeCapConfigIF = NULL;
7159 iTrackSelectionList[s].iTsDecNodePVInterfaceCapConfig = NULL;
7160 }
7161
7162 iTrackSelectionList[s].iTsTrackID = -1;
7163 iTrackSelectionList[s].iTsTrackValidForPlayableList = false;
7164 }
7165 }
7166 }
7167 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoTrackSelection() Out"));
7168 return retVal;
7169 }
7170
DoVerifyTrackInfo(PVPlayerEngineTrackSelection & aTrackSelection,PVMFTrackInfo * aTrack,PVMFStatus & aCheckcodec)7171 PVMFStatus PVPlayerEngine::DoVerifyTrackInfo(PVPlayerEngineTrackSelection &aTrackSelection, PVMFTrackInfo* aTrack, PVMFStatus& aCheckcodec)
7172 {
7173 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyTrackInfo() In %s", aTrack->getTrackMimeType().get_cstr()));
7174
7175 PVMFStatus status = PVMFSuccess;
7176 OsclMemAllocator alloc;
7177 PvmiKvp kvp;
7178 kvp.key = NULL;
7179
7180 const char* aFormatValType = PVMF_FORMAT_SPECIFIC_INFO_KEY;
7181 OsclRefCounterMemFrag aConfig;
7182
7183 kvp.length = oscl_strlen(aFormatValType) + 1; // +1 for \0
7184 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
7185 if (kvp.key == NULL)
7186 {
7187 return PVMFErrNoMemory;
7188 }
7189 oscl_strncpy(kvp.key, aFormatValType, kvp.length);
7190 aConfig = aTrack->getTrackConfigInfo();
7191 kvp.value.key_specific_value = (OsclAny*)(aConfig.getMemFragPtr());
7192 kvp.capacity = aConfig.getMemFragSize();
7193
7194 //Check if we have decoder node cap-config
7195 if (aTrackSelection.iTsDecNodeCapConfigIF != NULL)
7196 {
7197 PVMFFormatType DecnodeFormatType = aTrack->getTrackMimeType().get_str();
7198
7199 PvmiKvp* iErrorKVP = NULL;
7200 PvmiKvp iKVPSetFormat;
7201 iKVPSetFormat.key = NULL;
7202 OSCL_StackString<64> iKeyStringSetFormat;
7203 iKVPSetFormat.value.pChar_value = (char*)DecnodeFormatType.getMIMEStrPtr();
7204
7205 // Query for video decoder first with the track, if no success, then check for audio decoder. Only one query will succeed.
7206 // If both fails, check the status.
7207 iKeyStringSetFormat = _STRLIT_CHAR(PVMF_VIDEO_DEC_FORMAT_TYPE_VALUE_KEY);
7208 iKVPSetFormat.key = iKeyStringSetFormat.get_str();
7209
7210 aTrackSelection.iTsDecNodeCapConfigIF->setParametersSync(NULL, &iKVPSetFormat, 1, iErrorKVP);
7211 if (iErrorKVP == NULL)
7212 {
7213 //verify codec specific info
7214 int32 leavecode = 0;
7215 OSCL_TRY(leavecode, aCheckcodec = aTrackSelection.iTsDecNodeCapConfigIF->verifyParametersSync(NULL, &kvp, 1));
7216 OSCL_FIRST_CATCH_ANY(leavecode,
7217 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() unsupported verifyParametersSync did a leave!"));
7218 alloc.deallocate((OsclAny*)(kvp.key));
7219 aCheckcodec = PVMFSuccess; // set it success in case track selection info is not yet available;
7220 return PVMFSuccess;);
7221
7222 if (aCheckcodec != PVMFSuccess)
7223 {
7224 alloc.deallocate((OsclAny*)(kvp.key));
7225 //In case of other error code, this is operation error.
7226 if (aCheckcodec != PVMFErrNotSupported)
7227 {
7228 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on decoder node failed"));
7229 return aCheckcodec;
7230 }
7231 return status;
7232 }
7233
7234 int numKvp = 0;
7235 PvmiKvp* kvpPtr;
7236 // Query using get
7237 OSCL_StackString<64> querykey;
7238
7239 querykey = _STRLIT_CHAR("x-pvmf/video/render");
7240 if (aTrackSelection.iTsDecNodeCapConfigIF->getParametersSync(NULL, querykey.get_str(), kvpPtr, numKvp, NULL) == PVMFSuccess)
7241 {
7242 //verify width/height
7243 if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
7244 aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, kvpPtr, numKvp);
7245 status = aTrackSelection.iTsDecNodeCapConfigIF->releaseParameters(NULL, kvpPtr, numKvp);
7246 }
7247 }
7248 else
7249 {
7250 // Query failed for video decoder next try the audio decoder.
7251 iErrorKVP = NULL;
7252 iKeyStringSetFormat = NULL;
7253 iKVPSetFormat.key = NULL;
7254
7255 iKeyStringSetFormat += _STRLIT_CHAR(PVMF_AUDIO_DEC_FORMAT_TYPE_VALUE_KEY);
7256 iKVPSetFormat.key = iKeyStringSetFormat.get_str();
7257
7258 aTrackSelection.iTsDecNodeCapConfigIF->setParametersSync(NULL, &iKVPSetFormat, 1, iErrorKVP);
7259
7260 if (iErrorKVP == NULL)
7261 {
7262 //verify codec specific info
7263 int32 leavecodeaudio = 0;
7264 OSCL_TRY(leavecodeaudio, aCheckcodec = aTrackSelection.iTsDecNodeCapConfigIF->verifyParametersSync(NULL, &kvp, 1));
7265 OSCL_FIRST_CATCH_ANY(leavecodeaudio,
7266 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() unsupported verifyParametersSync did a leave!"));
7267 alloc.deallocate((OsclAny*)(kvp.key));
7268 aCheckcodec = PVMFSuccess; // set it success in case track selection info is not yet available;
7269 return PVMFSuccess;);
7270
7271 if (aCheckcodec != PVMFSuccess)
7272 {
7273 alloc.deallocate((OsclAny*)(kvp.key));
7274 //In case of other error code, this is operation error.
7275 if (aCheckcodec != PVMFErrNotSupported)
7276 {
7277 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on decoder node failed"));
7278 return aCheckcodec;
7279 }
7280 return status;
7281 }
7282
7283 int numKvp = 0;
7284 PvmiKvp* kvpPtr;
7285 // Query using get
7286 OSCL_StackString<64> querykey;
7287
7288 querykey = _STRLIT_CHAR("x-pvmf/audio/render");
7289 if (aTrackSelection.iTsDecNodeCapConfigIF->getParametersSync(NULL, querykey.get_str(), kvpPtr, numKvp, NULL) == PVMFSuccess)
7290 {
7291 //verify samplerate and channels
7292 if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
7293 aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, kvpPtr, numKvp);
7294 status = aTrackSelection.iTsDecNodeCapConfigIF->releaseParameters(NULL, kvpPtr, numKvp);
7295 }
7296 }
7297 }
7298 }
7299 else
7300 {
7301 if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
7302 {
7303 aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, &kvp, 1);
7304 }
7305 }
7306
7307 alloc.deallocate((OsclAny*)(kvp.key));
7308 if (aCheckcodec != PVMFSuccess)
7309 {
7310 //In case of other error code, this is operation error.
7311 if (aCheckcodec != PVMFErrNotSupported)
7312 {
7313 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on sink node failed"));
7314 return aCheckcodec;
7315 }
7316 return status;
7317 }
7318
7319 //verify bitrate
7320 PvmiKvp iKVPBitRate;
7321 iKVPBitRate.key = NULL;
7322
7323 OSCL_StackString<64> iKVPStringBitRate = _STRLIT_CHAR(PVMF_BITRATE_VALUE_KEY);
7324 iKVPBitRate.key = iKVPStringBitRate.get_str();
7325 iKVPBitRate.value.uint32_value = aTrack->getTrackBitRate();
7326
7327 if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
7328 aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, &iKVPBitRate, 1);
7329 //In case of other error code, this is operation error.
7330 if (aCheckcodec != PVMFSuccess)
7331 {
7332 //In case of other error code, this is operation error.
7333 if (aCheckcodec != PVMFErrNotSupported)
7334 {
7335 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on sinknode bitrate failed"));
7336 return aCheckcodec;
7337 }
7338 return status;
7339 }
7340
7341 //verify video framerate, if track is not video, sink will return ErrNotSupported.
7342 if (aTrack->getTrackFrameRate() > 0)
7343 {
7344 PvmiKvp iKVPFrameRate;
7345 iKVPFrameRate.key = NULL;
7346
7347 OSCL_StackString<64> iKVPStringFrameRate = _STRLIT_CHAR(PVMF_FRAMERATE_VALUE_KEY);
7348 iKVPFrameRate.key = iKVPStringFrameRate.get_str();
7349 iKVPFrameRate.value.uint32_value = aTrack->getTrackFrameRate();
7350
7351 if (aTrackSelection.iTsSinkNodeCapConfigIF != NULL)
7352 aCheckcodec = aTrackSelection.iTsSinkNodeCapConfigIF->verifyParametersSync(NULL, &iKVPFrameRate, 1);
7353 //In case of other error code, this is operation error.
7354 if (aCheckcodec != PVMFErrNotSupported && aCheckcodec != PVMFSuccess)
7355 {
7356 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyTrackInfo() verifyParametersSync() on sink node framerate failed"));
7357 return aCheckcodec;
7358 }
7359 }
7360
7361 return status;
7362 }
7363
DoSinkNodeDecNodeReset(PVCommandId aCmdId,OsclAny * aCmdContext)7364 PVMFStatus PVPlayerEngine::DoSinkNodeDecNodeReset(PVCommandId aCmdId, OsclAny* aCmdContext)
7365 {
7366 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
7367 (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Tick=%d", OsclTickCount::TickCount()));
7368
7369 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() In"));
7370
7371 iNumPendingNodeCmd = 0;
7372 PVMFCommandId cmdid = -1;
7373 int32 leavecode = 0;
7374
7375 for (uint32 i = 0; i < iDatapathList.size(); ++i)
7376 {
7377 if (iDatapathList[i].iSinkNode != NULL)
7378 {
7379 // Call Reset() on the sink node
7380 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeDecNodeReset);
7381
7382 leavecode = IssueSinkNodeReset(&(iDatapathList[i]), (OsclAny*) context, cmdid);
7383
7384 if (cmdid != -1 && leavecode == 0)
7385 {
7386 ++iNumPendingNodeCmd;
7387 }
7388 else
7389 {
7390 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Reset on sink node leaved, asserting"));
7391 FreeEngineContext(context);
7392 OSCL_ASSERT(false);
7393 }
7394 }
7395
7396 if (iDatapathList[i].iDecNode != NULL)
7397 {
7398 // Call Reset() on the dec node
7399 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeDecNodeReset);
7400
7401 leavecode = IssueDecNodeReset(iDatapathList[i].iDecNode, iDatapathList[i].iDecNodeSessionId, (OsclAny*) context, cmdid);
7402
7403 if (cmdid != -1 && leavecode == 0)
7404 {
7405 ++iNumPendingNodeCmd;
7406 }
7407 else
7408 {
7409 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Reset on sink node leaved, asserting"));
7410 FreeEngineContext(context);
7411 OSCL_ASSERT(false);
7412 }
7413 }
7414 }
7415
7416 // There can be some more decoders in TrackSelectionList on which engine needs to call Reset. call Reset on those decoders now.
7417 for (uint32 j = 0; j < iTrackSelectionList.size(); j++)
7418 {
7419 if (iTrackSelectionList[j].iTsDecNode != NULL)
7420 {
7421 // Call Reset() on the dec node
7422 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iTrackSelectionList[j].iTsDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeDecNodeReset);
7423
7424 leavecode = IssueDecNodeReset(iTrackSelectionList[j].iTsDecNode, iTrackSelectionList[j].iTsDecNodeSessionId, (OsclAny*) context, cmdid);
7425
7426 if (cmdid != -1 && leavecode == 0)
7427 {
7428 ++iNumPendingNodeCmd;
7429 }
7430 else
7431 {
7432 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Reset on sink node leaved, asserting"));
7433 FreeEngineContext(context);
7434 OSCL_ASSERT(false);
7435 }
7436 }
7437 }
7438
7439 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() Out"));
7440 if (iNumPendingNodeCmd == 0)
7441 {
7442 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeDecNodeReset() No datapath could be prepared!"));
7443 return PVMFFailure;
7444 }
7445 else
7446 {
7447 return PVMFSuccess;
7448 }
7449 }
7450
DoSinkDecCleanupSourcePrepare(PVCommandId aCmdId,OsclAny * aCmdContext)7451 PVMFStatus PVPlayerEngine::DoSinkDecCleanupSourcePrepare(PVCommandId aCmdId, OsclAny* aCmdContext)
7452 {
7453 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
7454 (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Tick=%d", OsclTickCount::TickCount()));
7455
7456 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() In"));
7457
7458 uint32 i = 0;
7459 //Destroy created temporal decoder node and sink node
7460 for (i = 0; i < iTrackSelectionList.size(); ++i)
7461 {
7462 if (iTrackSelectionList[i].iTsDecNode != NULL)
7463 {
7464 if (iTrackSelectionList[i].iTsDecNodeCapConfigIF)
7465 iTrackSelectionList[i].iTsDecNodeCapConfigIF = NULL;
7466 PVMFStatus status = PVMFFailure;
7467 status = iTrackSelectionList[i].iTsDecNode->Disconnect(iTrackSelectionList[i].iTsDecNodeSessionId);
7468 if (status == PVMFFailure)
7469 {
7470 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on dec node Failed"));
7471 OSCL_ASSERT(false);
7472 }
7473 status = iTrackSelectionList[i].iTsDecNode->ThreadLogoff();
7474 if (status == PVMFFailure)
7475 {
7476 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on dec node Failed"));
7477 OSCL_ASSERT(false);
7478 }
7479 PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
7480 for (; iter != iNodeUuids.end(); ++iter)
7481 if (iter->iNode == iTrackSelectionList[i].iTsDecNode)
7482 break;
7483
7484 if (iter != iNodeUuids.end())
7485 {
7486 bool release_status = false;
7487
7488 release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, iTrackSelectionList[i].iTsDecNode);
7489 if (release_status == false)
7490 {
7491 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Factory returned false while releasing the decnode"));
7492 OSCL_ASSERT(false);
7493 return PVMFFailure;
7494 }
7495
7496 iNodeUuids.erase(iter);
7497 iTrackSelectionList[i].iTsDecNode = NULL;
7498 }
7499 else
7500 {
7501 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() decnode not found"));
7502 return PVMFFailure;
7503 }
7504 }
7505 if (iTrackSelectionList[i].iTsSinkNode != NULL)
7506 {
7507 for (uint32 j = 0; j < iDatapathList.size(); j++)
7508 {
7509 if (iDatapathList[j].iSinkNode == iTrackSelectionList[i].iTsSinkNode)
7510 {
7511 PVMFStatus status = PVMFFailure;
7512 status = iDatapathList[j].iSinkNode->Disconnect(iDatapathList[j].iSinkNodeSessionId);
7513 if (status == PVMFFailure)
7514 {
7515 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on sink node Failed"));
7516 OSCL_ASSERT(false);
7517 }
7518 status = iDatapathList[j].iSinkNode->ThreadLogoff();
7519 if (status == PVMFFailure)
7520 {
7521 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on sink node Failed"));
7522 OSCL_ASSERT(false);
7523 }
7524 if (iDatapathList[j].iSinkNodeCapConfigIF)
7525 iDatapathList[j].iSinkNodeCapConfigIF = NULL;
7526 if (iDatapathList[j].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
7527 {
7528 PVFileOutputNodeFactory::DeleteFileOutput(iDatapathList[j].iSinkNode);
7529 iDatapathList[j].iSinkNode = NULL;
7530 }
7531 else if (iDatapathList[j].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_SINKNODE)
7532 {
7533 iDatapathList[j].iSinkNode = NULL;
7534 }
7535 else
7536 {
7537 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Unsupported player data sink type"));
7538 return PVMFFailure;
7539 }
7540 }
7541 }
7542 }
7543 }
7544
7545 // Also go through the datapathList and if for any datapath TrackInfo is not created, delete that datapath
7546 for (i = 0; i < iDatapathList.size(); i++)
7547 {
7548 if (iDatapathList[i].iTrackInfo == NULL)
7549 {
7550 // destroy the sinks first.
7551 if (iDatapathList[i].iSinkNode != NULL)
7552 {
7553 PVMFStatus status = PVMFFailure;
7554 status = iDatapathList[i].iSinkNode->Disconnect(iDatapathList[i].iSinkNodeSessionId);
7555 if (status == PVMFFailure)
7556 {
7557 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on sink node Failed"));
7558 OSCL_ASSERT(false);
7559 }
7560 status = iDatapathList[i].iSinkNode->ThreadLogoff();
7561 if (status == PVMFFailure)
7562 {
7563 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on sink node Failed"));
7564 OSCL_ASSERT(false);
7565 }
7566 if (iDatapathList[i].iSinkNodeCapConfigIF)
7567 iDatapathList[i].iSinkNodeCapConfigIF = NULL;
7568 if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
7569 {
7570 PVFileOutputNodeFactory::DeleteFileOutput(iDatapathList[i].iSinkNode);
7571 iDatapathList[i].iSinkNode = NULL;
7572 }
7573 else if (iDatapathList[i].iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_SINKNODE)
7574 {
7575 iDatapathList[i].iSinkNode = NULL;
7576 }
7577 else
7578 {
7579 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Unsupported player data sink type"));
7580 return PVMFFailure;
7581 }
7582 }
7583
7584 // next delete the decoder nodes
7585 if (iDatapathList[i].iDecNode != NULL)
7586 {
7587 if (iDatapathList[i].iDecNodeCapConfigIF)
7588 iDatapathList[i].iDecNodeCapConfigIF = NULL;
7589 PVMFStatus status = PVMFFailure;
7590 status = iDatapathList[i].iDecNode->Disconnect(iDatapathList[i].iDecNodeSessionId);
7591 if (status == PVMFFailure)
7592 {
7593 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Disconnect on dec node Failed"));
7594 OSCL_ASSERT(false);
7595 }
7596 status = iDatapathList[i].iDecNode->ThreadLogoff();
7597 if (status == PVMFFailure)
7598 {
7599 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() ThreadLogoff on dec node Failed"));
7600 OSCL_ASSERT(false);
7601 }
7602 PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
7603 for (; iter != iNodeUuids.end(); ++iter)
7604 if (iter->iNode == iDatapathList[i].iDecNode)
7605 break;
7606
7607 if (iter != iNodeUuids.end())
7608 {
7609 bool release_status = false;
7610
7611 release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, iDatapathList[i].iDecNode);
7612 if (release_status == false)
7613 {
7614 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Factory returned false while releasing the decnode"));
7615 OSCL_ASSERT(false);
7616 return PVMFFailure;
7617 }
7618
7619 iNodeUuids.erase(iter);
7620 iDatapathList[i].iDecNode = NULL;
7621 }
7622 else
7623 {
7624 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() decnode not found"));
7625 return PVMFFailure;
7626 }
7627 }
7628 }
7629 }
7630
7631 // Reset the Presentation Info list
7632 iSourcePresInfoList.Reset();
7633
7634 // Clear the Track selection List
7635 iTrackSelectionList.clear();
7636
7637 PVMFStatus cmdstatus = PVMFFailure;
7638
7639 // Notify the TargetNPT to the source node before calling Prepare.
7640 if (iSourceNodePBCtrlIF)
7641 {
7642 cmdstatus = iSourceNodePBCtrlIF->NotifyTargetPositionSync(iTargetNPT);
7643 }
7644 if (cmdstatus == PVMFSuccess || cmdstatus == PVMFErrNotSupported)
7645 {
7646 // Prepare the source node
7647 cmdstatus = DoSourceNodePrepare(aCmdId, aCmdContext);
7648 }
7649 if (cmdstatus != PVMFSuccess)
7650 {
7651 bool ehPending = CheckForPendingErrorHandlingCmd();
7652 if (ehPending)
7653 {
7654 // there should be no error handling queued.
7655 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Already EH pending, should never happen"));
7656 return PVMFPending;
7657 }
7658 else
7659 {
7660 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
7661 (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() DoSourceNodePrepare failed, Add EH command"));
7662 iCommandCompleteErrMsgInErrorHandling = NULL;
7663 iCommandCompleteStatusInErrorHandling = cmdstatus;
7664 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
7665 }
7666 return PVMFFailure;
7667 }
7668
7669 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkDecCleanupSourcePrepare() Out"));
7670 return PVMFSuccess;
7671 }
7672
DoSourceNodePrepare(PVCommandId aCmdId,OsclAny * aCmdContext)7673 PVMFStatus PVPlayerEngine::DoSourceNodePrepare(PVCommandId aCmdId, OsclAny* aCmdContext)
7674 {
7675 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
7676 (0, "PVPlayerEngine::DoSourceNodePrepare() Tick=%d", OsclTickCount::TickCount()));
7677
7678 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePrepare() In"));
7679
7680 if (iSourceNode == NULL)
7681 {
7682 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePrepare() Source node not available."));
7683 return PVMFFailure;
7684 }
7685
7686 // If source node is already in Prepared state then don't call Prepare()
7687 if (iSourceNode->GetState() == EPVMFNodePrepared)
7688 {
7689 // Datapaths are already set during intelligent track selection, just query for optional interfaces.
7690 iNumPendingDatapathCmd = 0;
7691 for (uint32 i = 0; i < iDatapathList.size(); ++i)
7692 {
7693 if (iDatapathList[i].iTrackInfo != NULL)
7694 {
7695 PVMFStatus cmdstatus = DoSinkNodeQueryInterfaceOptional(iDatapathList[i], aCmdId, aCmdContext);
7696 if (cmdstatus == PVMFSuccess)
7697 {
7698 ++iNumPendingDatapathCmd;
7699 }
7700 }
7701 }
7702
7703 if (iNumPendingDatapathCmd == 0)
7704 {
7705 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePrepare() No datapath could be prepared!"));
7706 return PVMFFailure;
7707 }
7708 else
7709 {
7710 return PVMFSuccess;
7711 }
7712 }
7713
7714 // Call Prepare() on the source node
7715 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodePrepare);
7716
7717 PVMFCommandId cmdid = -1;
7718 int32 leavecode = 0;
7719 OSCL_TRY(leavecode, cmdid = iSourceNode->Prepare(iSourceNodeSessionId, (OsclAny*)context));
7720 OSCL_FIRST_CATCH_ANY(leavecode,
7721 FreeEngineContext(context);
7722 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePrepare() Prepare on iSourceNode did a leave!"));
7723 return PVMFFailure);
7724
7725 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePrepare() Out"));
7726
7727 return PVMFSuccess;
7728 }
7729
DoSinkNodeQueryInterfaceOptional(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)7730 PVMFStatus PVPlayerEngine::DoSinkNodeQueryInterfaceOptional(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
7731 {
7732 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
7733 (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
7734
7735 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
7736
7737 int32 leavecode = 0;
7738
7739 // Request optional extension interface from the sink node
7740 PVPlayerEngineContext* context = NULL;
7741 PVMFCommandId cmdid = -1;
7742 aDatapath.iNumPendingCmd = 0;
7743
7744 // Request the sync control interface for the sink node
7745 context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeQuerySyncCtrlIF);
7746 cmdid = -1;
7747 leavecode = 0;
7748 aDatapath.iSinkNodePVInterfaceSyncCtrl = NULL;
7749 OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->QueryInterface(aDatapath.iSinkNodeSessionId, PvmfNodesSyncControlUuid, aDatapath.iSinkNodePVInterfaceSyncCtrl, (OsclAny*)context));
7750 if (leavecode)
7751 {
7752 aDatapath.iSinkNodePVInterfaceSyncCtrl = NULL;
7753 FreeEngineContext(context);
7754 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() QueryInterface on sink node for sync control IF did a leave!"));
7755 }
7756 else
7757 {
7758 ++aDatapath.iNumPendingCmd;
7759 }
7760
7761 // Query for Metadata IF
7762 context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeQueryMetadataIF);
7763 PVUuid metadatauuid = KPVMFMetadataExtensionUuid;
7764 cmdid = -1;
7765 leavecode = 0;
7766 aDatapath.iSinkNodePVInterfaceMetadataExt = NULL;
7767 OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->QueryInterface(aDatapath.iSinkNodeSessionId, metadatauuid, aDatapath.iSinkNodePVInterfaceMetadataExt, (OsclAny*)context));
7768 if (leavecode)
7769 {
7770 aDatapath.iSinkNodePVInterfaceMetadataExt = NULL;
7771 FreeEngineContext(context);
7772 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() QueryInterface on sink node for metadata IF did a leave!"));
7773 }
7774 else
7775 {
7776 ++aDatapath.iNumPendingCmd;
7777 }
7778
7779 if (aDatapath.iNumPendingCmd > 0)
7780 {
7781 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() Out"));
7782 return PVMFSuccess;
7783 }
7784 else
7785 {
7786 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeQueryInterfaceOptional() Out No pending QueryInterface() on sink node"));
7787 return PVMFErrNotSupported;
7788 }
7789 }
7790
DoDecNodeQueryInterfaceOptional(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)7791 PVMFStatus PVPlayerEngine::DoDecNodeQueryInterfaceOptional(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
7792 {
7793 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
7794 (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
7795
7796 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
7797
7798 // Check if the dec node is present
7799 if (aDatapath.iDecNode == NULL)
7800 {
7801 return PVMFErrNotSupported;
7802 }
7803
7804 PVPlayerEngineContext* context = NULL;
7805 PVMFCommandId cmdid = -1;
7806 int32 leavecode = 0;
7807
7808 aDatapath.iNumPendingCmd = 0;
7809
7810 // Query for Metadata IF
7811 context = AllocateEngineContext(&aDatapath, aDatapath.iDecNode, NULL, aCmdId, aCmdContext, PVP_CMD_DecNodeQueryMetadataIF);
7812 PVUuid metadatauuid = KPVMFMetadataExtensionUuid;
7813 cmdid = -1;
7814 leavecode = 0;
7815 aDatapath.iDecNodePVInterfaceMetadataExt = NULL;
7816 OSCL_TRY(leavecode, cmdid = aDatapath.iDecNode->QueryInterface(aDatapath.iDecNodeSessionId, metadatauuid, aDatapath.iDecNodePVInterfaceMetadataExt, (OsclAny*)context));
7817 if (leavecode)
7818 {
7819 aDatapath.iDecNodePVInterfaceMetadataExt = NULL;
7820 FreeEngineContext(context);
7821 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() QueryInterface on dec node for metadata IF did a leave!"));
7822 }
7823 else
7824 {
7825 ++aDatapath.iNumPendingCmd;
7826 }
7827
7828 if (aDatapath.iNumPendingCmd > 0)
7829 {
7830 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() Out"));
7831 return PVMFSuccess;
7832 }
7833 else
7834 {
7835 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDecNodeQueryInterfaceOptional() Out No pending QueryInterface() on dec node"));
7836 return PVMFErrNotSupported;
7837 }
7838 }
7839
7840
DoDatapathPrepare(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)7841 PVMFStatus PVPlayerEngine::DoDatapathPrepare(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
7842 {
7843 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
7844 (0, "PVPlayerEngine::DoDatapathPrepare() for %s Tick=%d",
7845 aDatapath.iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
7846
7847 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPrepare() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
7848 int32 leavecode = 0;
7849
7850 // Create the datapath utility object
7851 if (aDatapath.iDatapath == NULL)
7852 {
7853 leavecode = 0;
7854 OSCL_TRY(leavecode, aDatapath.iDatapath = OSCL_NEW(PVPlayerDatapath, ()));
7855 OSCL_FIRST_CATCH_ANY(leavecode,
7856 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathPrepare() Could not create datapath object"));
7857 return PVMFErrNoMemory);
7858 }
7859
7860 // Configure the datapath utility based on datapath configuration
7861 aDatapath.iDatapath->SetObserver(*this, *this, *this);
7862 aDatapath.iDatapath->SetSourceNode(iSourceNode);
7863 aDatapath.iDatapath->SetSinkNode(aDatapath.iSinkNode);
7864
7865 if (aDatapath.iDecNode)
7866 {
7867 aDatapath.iDatapath->SetDecNode(aDatapath.iDecNode);
7868 aDatapath.iDatapath->SetSourceDecTrackInfo(*(aDatapath.iTrackInfo));
7869 aDatapath.iDatapath->SetDecSinkFormatType(aDatapath.iSinkFormat);
7870 }
7871 else
7872 {
7873 aDatapath.iDatapath->SetSourceSinkTrackInfo(*(aDatapath.iTrackInfo));
7874 }
7875
7876 // Prepare the datapath
7877 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPPrepare);
7878
7879 PVMFStatus retval = aDatapath.iDatapath->Prepare((OsclAny*)context);
7880 if (retval != PVMFSuccess)
7881 {
7882 FreeEngineContext(context);
7883 }
7884
7885 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPrepare() Out"));
7886 return retval;
7887 }
7888
7889
DoSourceNodeQueryDataSourcePosition(PVCommandId aCmdId,OsclAny * aCmdContext)7890 PVMFStatus PVPlayerEngine::DoSourceNodeQueryDataSourcePosition(PVCommandId aCmdId, OsclAny* aCmdContext)
7891 {
7892 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() In"));
7893
7894 // Check if the source node has position control IF
7895 if (iSourceNodePBCtrlIF == NULL)
7896 {
7897 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Playback control IF on source node not available"));
7898 return PVMFErrNotSupported;
7899 }
7900
7901 uint32 timems = 0;
7902 if (iCurrentBeginPosition.iIndeterminate == false)
7903 {
7904 // Convert beginning position to milliseconds
7905 PVMFStatus retval = ConvertToMillisec(iCurrentBeginPosition, timems);
7906 if (retval != PVMFSuccess)
7907 {
7908 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Converting to millisec failed"));
7909 return retval;
7910 }
7911 }
7912
7913 PVMFCommandId cmdid = -1;
7914
7915 if (iSeekToSyncPoint && iSyncPointSeekWindow > 0)
7916 {
7917 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryDataSourcePosition);
7918
7919 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Calling QueryDataSourcePosition() Starting pos %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
7920 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Calling QueryDataSourcePosition() Starting pos %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
7921 // As in case of MP4 file we need to call overload function of QueryDataSourcePosition which retruns
7922 // I frame before and after instead of actaul NPT, format type will be checked here to first find if
7923 // format-type is one of the MP4 varient
7924
7925 PVMFNodeCapability nodeCapability;
7926 iSourceNode->GetCapability(nodeCapability);
7927 PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
7928 bool mpeg4FormatType = false;
7929 if (formatType != NULL)
7930 {
7931 if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
7932 {
7933 mpeg4FormatType = true;
7934 }
7935 else
7936 {
7937 mpeg4FormatType = false;
7938 }
7939 }
7940 int32 leavecode = 0;
7941 if (mpeg4FormatType)
7942 {
7943 OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT,
7944 iSeekPointBeforeTargetNPT, iSeekPointAfterTargetNPT, (OsclAny*) context, iSeekToSyncPoint));
7945 }
7946 else
7947 {
7948 OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->QueryDataSourcePosition(iSourceNodeSessionId, iTargetNPT, iActualNPT,
7949 iSeekToSyncPoint, (OsclAny*)context));
7950 }
7951
7952 if (leavecode != 0)
7953 {
7954 FreeEngineContext(context);
7955 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() QueryDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
7956 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
7957 {
7958 // Since position query is not supported, assume the repositioning will
7959 // go to the requested position
7960 // Do the source positioning
7961 return DoSourceNodeSetDataSourcePosition(aCmdId, aCmdContext);
7962 }
7963 else
7964 {
7965 return PVMFFailure;
7966 }
7967 }
7968 }
7969 else
7970 {
7971 // Go straight to repositioning the data source
7972 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition: Straight call SetDataSourcePosition Starting pos %d ms, SeekToSyncPt %d", iTargetNPT, iSeekToSyncPoint));
7973 return DoSourceNodeSetDataSourcePosition(aCmdId, aCmdContext);
7974 }
7975
7976 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeQueryDataSourcePosition() Out"));
7977
7978 return PVMFSuccess;
7979 }
7980
7981
DoSourceNodeSetDataSourcePosition(PVCommandId aCmdId,OsclAny * aCmdContext)7982 PVMFStatus PVPlayerEngine::DoSourceNodeSetDataSourcePosition(PVCommandId aCmdId, OsclAny* aCmdContext)
7983 {
7984 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() In"));
7985
7986 // Check if the source node has position control IF
7987 if (iSourceNodePBCtrlIF == NULL)
7988 {
7989 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() Playback control IF on source node not available"));
7990 // Since repositioning IF is not supported by this source node, assume the playback
7991 // will start from time 0
7992 iActualNPT = 0;
7993 iActualMediaDataTS = 0;
7994 iSkipMediaDataTS = 0;
7995 // Then continue to handle like success case
7996 iStartNPT = 0;
7997 iStartMediaDataTS = 0;
7998 // Save the actual starting position for GetPlaybackRange() query
7999 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
8000 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
8001 iTargetNPT = iActualNPT;
8002
8003 // Repositioning so reset the EOS received flag for each active datapath
8004 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8005 {
8006 if (iDatapathList[i].iDatapath)
8007 {
8008 iDatapathList[i].iEndOfDataReceived = false;
8009 }
8010 }
8011
8012 // Start the source node
8013 return DoSourceNodeStart(aCmdId, aCmdContext);
8014 }
8015
8016 // Set the position of the source node
8017 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourcePosition);
8018
8019 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() Calling SetDataSourcePosition() TargetNPT %d ms, SeekToSyncPoint %d", iTargetNPT, iSeekToSyncPoint));
8020
8021 int32 leavecode = 0;
8022 PVMFCommandId cmdid = -1;
8023
8024 OSCL_TRY(leavecode, cmdid = iSourceNodePBCtrlIF->SetDataSourcePosition(iSourceNodeSessionId, iTargetNPT, iActualNPT, iActualMediaDataTS, iSeekToSyncPoint, iStreamID, (OsclAny*)context));
8025 OSCL_FIRST_CATCH_ANY(leavecode,
8026 FreeEngineContext(context);
8027 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() SetDataSourcePosition on iSourceNodePBCtrlIF did a leave!"));
8028 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
8029 {
8030 // Since this repositioning was not supported, assume the playback
8031 // will start from same location as before reposition request.
8032 PVPPlaybackPosition curpos;
8033 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
8034 GetPlaybackClockPosition(curpos);
8035 uint32 clockcurpos = 0;
8036 bool tmpbool = false;
8037 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
8038
8039 // since repositioning is not supported continue playing from current position.
8040 iWatchDogTimerInterval = 0;
8041 iActualNPT = curpos.iPosValue.millisec_value;
8042 iActualMediaDataTS = clockcurpos;
8043 iSkipMediaDataTS = clockcurpos;
8044
8045 iStartNPT = iActualNPT;
8046 iStartMediaDataTS = iSkipMediaDataTS;
8047
8048 // also decrement the stream id as no skip will be called on MIO node.
8049 --iStreamID;
8050
8051 // Save the actual starting position for GetPlaybackRange() query
8052 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
8053 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
8054 iTargetNPT = iActualNPT;
8055
8056 // Repositioning so reset the EOS received flag for each active datapath
8057 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8058 {
8059 if (iDatapathList[i].iDatapath)
8060 {
8061 iDatapathList[i].iEndOfDataReceived = false;
8062 }
8063 }
8064
8065 // Start the source node
8066 return DoSourceNodeStart(aCmdId, aCmdContext);
8067 }
8068 else
8069 {
8070 return PVMFFailure;
8071 }
8072 );
8073
8074 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourcePosition() Out"));
8075
8076 return PVMFSuccess;
8077 }
8078
DoSourceNodeSetDataSourceDirection(PVCommandId aCmdId,OsclAny * aCmdContext)8079 PVMFStatus PVPlayerEngine::DoSourceNodeSetDataSourceDirection(PVCommandId aCmdId, OsclAny* aCmdContext)
8080 {
8081 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() In"));
8082
8083 if (iChangePlaybackDirectionWhenResuming)
8084 {
8085 //Setting direction during engine Resume, due to a SetPlaybackRate that
8086 //occurred during engine Paused state.
8087
8088 // Check if the source node has position control IF
8089 if (iSourceNodeDirCtrlIF == NULL)
8090 {
8091 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Direction control IF on source node not available"));
8092
8093 // Since repositioning IF is not supported by this source node, assume the playback
8094 // will start from time 0
8095 iActualNPT = 0;
8096 iActualMediaDataTS = 0;
8097 iSkipMediaDataTS = 0;
8098 // Then continue to handle like success case
8099 iStartNPT = 0;
8100 iStartMediaDataTS = 0;
8101 // Save the actual starting position for GetPlaybackRange() query
8102 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
8103 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
8104 iTargetNPT = iActualNPT;
8105
8106 // Repositioning so reset the EOS flag for each active datapath
8107 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8108 {
8109 if (iDatapathList[i].iDatapath)
8110 {
8111 iDatapathList[i].iEndOfDataReceived = false;
8112 }
8113 }
8114
8115 return PVMFErrNotSupported;
8116 }
8117
8118 // Set the position of the source node
8119 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourceDirection);
8120
8121 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Calling SetDataSourcePosition() "));
8122
8123 int32 leavecode = 0;
8124 PVMFCommandId cmdid = -1;
8125 OSCL_TRY(leavecode, cmdid = iSourceNodeDirCtrlIF->SetDataSourceDirection(iSourceNodeSessionId
8126 , (iPlaybackDirection_New < 0) ? PVMF_DATA_SOURCE_DIRECTION_REVERSE : PVMF_DATA_SOURCE_DIRECTION_FORWARD
8127 , iActualNPT
8128 , iActualMediaDataTS
8129 , iOutsideTimebase
8130 , (OsclAny*)context));
8131 OSCL_FIRST_CATCH_ANY(leavecode,
8132 FreeEngineContext(context);
8133 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() SetDataSourceDirection on iSourceNodeDirCtrlIF did a leave!"));
8134 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
8135 {
8136 // Since this repositioning was not supported, assume the playback
8137 // will start from same location as before repos request.
8138 PVPPlaybackPosition curpos;
8139 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
8140 GetPlaybackClockPosition(curpos);
8141 uint32 clockcurpos = 0;
8142 bool tmpbool = false;
8143 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
8144
8145 // since repositioning is not supported continue playing from current position.
8146 iWatchDogTimerInterval = 0;
8147 iActualNPT = curpos.iPosValue.millisec_value;
8148 iActualMediaDataTS = clockcurpos;
8149 iSkipMediaDataTS = clockcurpos;
8150
8151 iStartNPT = iActualNPT;
8152 iStartMediaDataTS = iSkipMediaDataTS;
8153
8154 // Save the actual starting position for GetPlaybackRange() query
8155 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
8156 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
8157 iTargetNPT = iActualNPT;
8158
8159 // Repositioning so reset the EOS flag for each active datapath
8160 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8161 {
8162 if (iDatapathList[i].iDatapath)
8163 {
8164 iDatapathList[i].iEndOfDataReceived = false;
8165 }
8166 }
8167
8168 return PVMFErrNotSupported;
8169 }
8170 else
8171 {
8172 return PVMFFailure;
8173 }
8174 );
8175
8176 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Out"));
8177
8178 return PVMFSuccess;
8179 }
8180 else
8181 {
8182 //changing direction during SetPlaybackRate command
8183
8184 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() In"));
8185
8186 // Check if the source node has direction control IF
8187 if (iSourceNodeDirCtrlIF == NULL)
8188 {
8189 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() No source direction control IF"));
8190 return PVMFFailure;
8191 }
8192
8193 // Pause the playback clock
8194 bool clockpausedhere = iPlaybackClock.Pause();
8195
8196 // Set the new direction on the source node
8197 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeSetDataSourceDirection);
8198
8199 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Calling SetDataSourceDirection() on source node."));
8200
8201 int32 leavecode = 0;
8202 PVMFCommandId cmdid = -1;
8203 OSCL_TRY(leavecode, cmdid = iSourceNodeDirCtrlIF->SetDataSourceDirection(iSourceNodeSessionId
8204 , (iPlaybackDirection_New < 0) ? PVMF_DATA_SOURCE_DIRECTION_REVERSE : PVMF_DATA_SOURCE_DIRECTION_FORWARD
8205 , iActualNPT
8206 , iActualMediaDataTS
8207 , iOutsideTimebase_New
8208 , (OsclAny*)context));
8209 OSCL_FIRST_CATCH_ANY(leavecode,
8210 FreeEngineContext(context);
8211 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() SetDataSourceDirection on iSourceNodeDirCtrlIF did a leave!"));
8212 if (clockpausedhere)
8213 {
8214 // Resume the clock if paused in this function
8215 StartPlaybackClock();
8216 }
8217
8218 if (leavecode == PVMFErrNotSupported || leavecode == PVMFErrArgument)
8219 {
8220 return leavecode;
8221 }
8222 else
8223 {
8224 return PVMFFailure;
8225 }
8226 );
8227
8228 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeSetDataSourceDirection() Out"));
8229
8230 return PVMFSuccess;
8231 //wait on node command complete and a call to HandleSourceNodeSetDataSourceDirection
8232 }
8233 }
8234
DoSourceNodeStart(PVCommandId aCmdId,OsclAny * aCmdContext)8235 PVMFStatus PVPlayerEngine::DoSourceNodeStart(PVCommandId aCmdId, OsclAny* aCmdContext)
8236 {
8237 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
8238 (0, "PVPlayerEngine::DoSourceNodeStart() Tick=%d", OsclTickCount::TickCount()));
8239
8240 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStart() In"));
8241
8242 if (iSourceNode == NULL)
8243 {
8244 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStart() Source node not available."));
8245 return PVMFFailure;
8246 }
8247
8248 // Start the source node
8249 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeStart);
8250
8251 PVMFCommandId cmdid = -1;
8252 int32 leavecode = 0;
8253 OSCL_TRY(leavecode, cmdid = iSourceNode->Start(iSourceNodeSessionId, (OsclAny*)context));
8254 OSCL_FIRST_CATCH_ANY(leavecode,
8255 FreeEngineContext(context);
8256 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStart() Start on iSourceNode did a leave!"));
8257 return PVMFFailure);
8258
8259 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStart() Out"));
8260
8261 return PVMFSuccess;
8262 }
8263
8264
DoDatapathStart(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)8265 PVMFStatus PVPlayerEngine::DoDatapathStart(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
8266 {
8267 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
8268 (0, "PVPlayerEngine::DoDatapathStart() for %s Tick=%d",
8269 aDatapath.iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
8270
8271 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStart() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
8272
8273 // Start the datapath
8274 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPStart);
8275
8276 PVMFStatus retval = aDatapath.iDatapath->Start((OsclAny*)context);
8277 if (retval != PVMFSuccess)
8278 {
8279 FreeEngineContext(context);
8280 }
8281
8282 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStart() Out"));
8283 return retval;
8284 }
8285
8286
DoSinkNodeSkipMediaData(PVCommandId aCmdId,OsclAny * aCmdContext)8287 PVMFStatus PVPlayerEngine::DoSinkNodeSkipMediaData(PVCommandId aCmdId, OsclAny* aCmdContext)
8288 {
8289 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
8290 (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() Tick=%d", OsclTickCount::TickCount()));
8291
8292 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() In"));
8293
8294 // Tell the sink nodes to skip the unneeded media data
8295 iNumPendingNodeCmd = 0;
8296 int32 leavecode = 0;
8297
8298 // Call SkipMediaData() for each active datapath with sink nodes that have the sync control IF
8299 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8300 {
8301 if (iDatapathList[i].iDatapath &&
8302 iDatapathList[i].iEndOfDataReceived == false &&
8303 iDatapathList[i].iSinkNodeSyncCtrlIF)
8304 {
8305 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeSkipMediaData);
8306
8307 leavecode = IssueSinkSkipMediaData(&(iDatapathList[i]), false, (OsclAny*) context);
8308 if (leavecode == 0)
8309 {
8310 ++iNumPendingNodeCmd;
8311 ++iNumPendingSkipCompleteEvent;
8312 ++iNumPVMFInfoStartOfDataPending;
8313 }
8314 else
8315 {
8316 FreeEngineContext(context);
8317 }
8318 }
8319 }
8320
8321 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() Out"));
8322 if (iNumPendingNodeCmd > 0)
8323 {
8324 return PVMFSuccess;
8325 }
8326 else
8327 {
8328 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeSkipMediaData() Skip on sink nodes failed"));
8329 return PVMFFailure;
8330 }
8331 }
8332
8333
DoStart(PVPlayerEngineCommand & aCmd)8334 PVMFStatus PVPlayerEngine::DoStart(PVPlayerEngineCommand& aCmd)
8335 {
8336 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
8337 (0, "PVPlayerEngine::DoStart() Tick=%d", OsclTickCount::TickCount()));
8338
8339 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStart() In, State=%d", iState));
8340
8341 if (GetPVPlayerState() == PVP_STATE_STARTED)
8342 {
8343 if (iState == PVP_ENGINE_STATE_AUTO_PAUSED)
8344 {
8345 // Engine in AUTO-PAUSED state since it recieved an Underflow event
8346 // during Prepare. Set the engine state to STARTED and return success
8347 // Wait for DataReady event for the playback to start.
8348 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
8349 (0, "PVPlayerEngine::DoStart() Engine in auto-paused state, set it to started"));
8350 SetEngineState(PVP_ENGINE_STATE_STARTED);
8351 }
8352 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStart() Engine already in Started State"));
8353 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8354 return PVMFSuccess;
8355 }
8356
8357 if (iPlaybackPausedDueToEndOfClip)
8358 {
8359 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStart() Playback already paused due to End of clip"));
8360 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8361 return PVMFSuccess;
8362 }
8363 if (GetPVPlayerState() != PVP_STATE_PREPARED)
8364 {
8365 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStart() Wrong engine state"));
8366 return PVMFErrInvalidState;
8367 }
8368
8369 if (iNumPVMFInfoStartOfDataPending == 0)
8370 {
8371 // start the clock only if Skip is complete and InfoStartOfData has been received
8372 // Enable the end time check if specified
8373 UpdateCurrentEndPosition(iCurrentEndPosition);
8374 StartPlaybackClock();
8375 }
8376 else
8377 {
8378 // Sink nodes have not reported InfoStartOfData yet.
8379 // Check if WatchDogTimer has already been set or not,
8380 // if Timer has not been set or has expired then set it to a default value timer.
8381 if (!(iWatchDogTimer->IsBusy()))
8382 {
8383 // set a dafault timer
8384 iWatchDogTimerInterval = 0;
8385 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
8386 (0, "PVPlayerEngine::DoStart() Setting WatchDogTimer to a dafult value of 1 second"));
8387 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval); // this will set a timer to a default
8388 iWatchDogTimer->Start(); // value of 1 sec. since iWatchDogTimerInterval is zero.
8389 }
8390 }
8391
8392 SetEngineState(PVP_ENGINE_STATE_STARTED);
8393 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8394
8395 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStart() Out"));
8396 return PVMFSuccess;
8397 }
8398
8399
DoPause(PVPlayerEngineCommand & aCmd)8400 PVMFStatus PVPlayerEngine::DoPause(PVPlayerEngineCommand& aCmd)
8401 {
8402 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_NOTICE,
8403 (0, "PVPlayerEngine::DoPause() Tick=%d", OsclTickCount::TickCount()));
8404
8405 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPause() In"));
8406
8407 // Check engine state
8408 switch (GetPVPlayerState())
8409 {
8410 case PVP_STATE_PAUSED :
8411 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPause() Engine already in Paused State"));
8412 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8413 return PVMFSuccess;
8414
8415 case PVP_STATE_STARTED :
8416 break;
8417
8418 case PVP_STATE_PREPARED :
8419 if (aCmd.GetCmdType() == PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP)
8420 {
8421 //It is possible in repositioning to end use-case that
8422 //engine receives StartofData and EndofData before Prepare
8423 //completes. So we should not fail Pause, just process it.
8424 break;
8425 }
8426
8427 default:
8428 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Wrong engine state"));
8429 return PVMFErrInvalidState;
8430 }
8431
8432 // Send position update to app.
8433 SendPositionStatusUpdate();
8434
8435 // Stop the end time check timer
8436 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
8437
8438 // Stop the watchdog timer if active. We will Start the timer again in resume.
8439 // this should only be done when engine is waiting for StartofData info event
8440 // after reposition.
8441 if (iNumPVMFInfoStartOfDataPending > 0)
8442 {
8443 if (iWatchDogTimer->IsBusy())
8444 {
8445 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
8446 (0, "PVPlayerEngine::DoPause - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
8447 iWatchDogTimer->Cancel();
8448 }
8449 }
8450
8451 // Pause the clock and notify sinks if not auto-paused
8452 uint32 i;
8453 if (iState != PVP_ENGINE_STATE_AUTO_PAUSED)
8454 {
8455 // Pause the playback clock
8456 iPlaybackClock.Pause();
8457 // Notify data sinks that clock has paused
8458 for (i = 0; i < iDatapathList.size(); ++i)
8459 {
8460 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
8461 {
8462 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStopped();
8463 }
8464 }
8465 }
8466
8467 PVMFStatus retval = PVMFErrNotSupported;
8468
8469 // Issue pause to all active datapaths
8470 iNumPendingDatapathCmd = 0;
8471
8472 for (i = 0; i < iDatapathList.size(); ++i)
8473 {
8474 if (iDatapathList[i].iDatapath)
8475 {
8476 if (iState == PVP_ENGINE_STATE_AUTO_PAUSED)
8477 {
8478 // Since sinks are already paused in auto-pause state, skip pausing the sink in the datapath
8479 retval = DoDatapathPause(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext(), true);
8480 }
8481 else
8482 {
8483 // Pause all nodes in the datapath
8484 retval = DoDatapathPause(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext(), false);
8485 }
8486
8487 if (retval == PVMFSuccess)
8488 {
8489 ++iNumPendingDatapathCmd;
8490 }
8491 else
8492 {
8493 bool ehPending = CheckForPendingErrorHandlingCmd();
8494 if (ehPending)
8495 {
8496 // there should be no error handling queued.
8497 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Already EH pending, should never happen"));
8498 return PVMFPending;
8499 }
8500 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() DoDatapathPause Failed, Add EH command"));
8501 iCommandCompleteStatusInErrorHandling = retval;
8502 iCommandCompleteErrMsgInErrorHandling = NULL;
8503 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
8504 return PVMFPending;
8505 }
8506 }
8507 }
8508
8509 if (iNumPendingDatapathCmd == 0)
8510 {
8511 // If there are no active datapaths, continue on to pause the source node
8512 retval = DoSourceNodePause(aCmd.GetCmdId(), aCmd.GetContext());
8513 }
8514
8515 if (retval != PVMFSuccess)
8516 {
8517 bool ehPending = CheckForPendingErrorHandlingCmd();
8518 if (ehPending)
8519 {
8520 // there should be no error handling queued.
8521 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Already EH pending, should never happen"));
8522 return PVMFPending;
8523 }
8524 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoPause() Pausing datapath and source node failed, Add EH command"));
8525 iCommandCompleteStatusInErrorHandling = retval;
8526 iCommandCompleteErrMsgInErrorHandling = NULL;
8527 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
8528 return PVMFPending;
8529 }
8530
8531 // TEMP Until queued playback range is available
8532 // Reset the flag when doing a pause
8533 iChangePlaybackPositionWhenResuming = false;
8534 iChangePlaybackDirectionWhenResuming = false;
8535 // END TEMP
8536
8537 SetEngineState(PVP_ENGINE_STATE_PAUSING);
8538
8539 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoPause() Out"));
8540 return PVMFSuccess;
8541 }
8542
8543
DoDatapathPause(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext,bool aSinkPaused)8544 PVMFStatus PVPlayerEngine::DoDatapathPause(PVPlayerEngineDatapath& aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext, bool aSinkPaused)
8545 {
8546 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
8547 (0, "PVPlayerEngine::DoDatapathPause() for %s Tick=%d",
8548 aDatapath.iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
8549
8550 if (aDatapath.iTrackInfo == NULL)
8551 {
8552 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathPause() TrackInfo not available, failure"));
8553 return PVMFFailure;
8554 }
8555 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPause() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
8556
8557 // Pause the datapath
8558 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, -1);
8559
8560 PVMFStatus retval = aDatapath.iDatapath->Pause((OsclAny*)context, aSinkPaused);
8561 if (retval != PVMFSuccess)
8562 {
8563 FreeEngineContext(context);
8564 }
8565
8566 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathPause() Out"));
8567 return retval;
8568 }
8569
8570
DoSourceNodePause(PVCommandId aCmdId,OsclAny * aCmdContext)8571 PVMFStatus PVPlayerEngine::DoSourceNodePause(PVCommandId aCmdId, OsclAny* aCmdContext)
8572 {
8573 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePause() In"));
8574
8575 if (iSourceNode == NULL)
8576 {
8577 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePause() Source node not available"));
8578 return PVMFFailure;
8579 }
8580
8581 // Pause the source node
8582 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, -1);
8583
8584 PVMFCommandId cmdid = -1;
8585 int32 leavecode = 0;
8586 OSCL_TRY(leavecode, cmdid = iSourceNode->Pause(iSourceNodeSessionId, (OsclAny*)context));
8587 OSCL_FIRST_CATCH_ANY(leavecode,
8588 FreeEngineContext(context);
8589 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodePause() Pause on iSourceNode did a leave!"));
8590 return PVMFFailure);
8591
8592 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodePause() Out"));
8593
8594 return PVMFSuccess;
8595 }
8596
8597
DoResume(PVPlayerEngineCommand & aCmd)8598 PVMFStatus PVPlayerEngine::DoResume(PVPlayerEngineCommand& aCmd)
8599 {
8600 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoResume() In"));
8601 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoResume() iNumPendingSkipCompleteEvent: %d", iNumPendingSkipCompleteEvent));
8602
8603 if (GetPVPlayerState() == PVP_STATE_STARTED)
8604 {
8605 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Engine already in Started State"));
8606 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8607 return PVMFSuccess;
8608 }
8609
8610 // Check engine state
8611 if (GetPVPlayerState() != PVP_STATE_PAUSED)
8612 {
8613 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Wrong engine state"));
8614 return PVMFErrInvalidState;
8615 }
8616
8617 // Disallow resume when paused due to EOS and position/direction
8618 // hasn't been changed
8619 if (iPlaybackPausedDueToEndOfClip)
8620 {
8621 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Currently paused due to EOS so not allowed!"));
8622 return PVMFErrInvalidState;
8623 }
8624
8625 PVMFStatus retval;
8626 if (iChangePlaybackPositionWhenResuming)
8627 {
8628 // Reposition occurred during the paused state so need to change the source position first
8629 retval = DoSourceNodeQueryDataSourcePosition(aCmd.GetCmdId(), aCmd.GetContext());
8630 // ignore failure, continue on to Start
8631 if (retval != PVMFSuccess)
8632 {
8633 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
8634 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
8635 SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
8636 infomsg->removeRef();
8637 retval = DoSourceNodeStart(aCmd.GetCmdId(), aCmd.GetContext());
8638 }
8639 }
8640 else if (iChangePlaybackDirectionWhenResuming)
8641 {
8642 // Direction change occurred during the paused state so need to change the source direction first
8643 retval = DoSourceNodeSetDataSourceDirection(aCmd.GetCmdId(), aCmd.GetContext());
8644 // ignore failure, continue on to Start
8645 if (retval != PVMFSuccess)
8646 {
8647 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
8648 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
8649 SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
8650 infomsg->removeRef();
8651 retval = DoSourceNodeStart(aCmd.GetCmdId(), aCmd.GetContext());
8652 }
8653 }
8654 else
8655 {
8656 retval = DoSourceNodeStart(aCmd.GetCmdId(), aCmd.GetContext());
8657 }
8658
8659 if (retval != PVMFSuccess)
8660 {
8661 bool ehPending = CheckForPendingErrorHandlingCmd();
8662 if (ehPending)
8663 {
8664 // there should be no error handling queued.
8665 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Already EH pending, should never happen"));
8666 return PVMFPending;
8667 }
8668 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoResume() Resuming source node or changing position failed, Add EH command"));
8669 iCommandCompleteStatusInErrorHandling = retval;
8670 iCommandCompleteErrMsgInErrorHandling = NULL;
8671 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
8672 return PVMFPending;
8673 }
8674
8675 SetEngineState(PVP_ENGINE_STATE_RESUMING);
8676
8677 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoResume() Out"));
8678 return PVMFSuccess;
8679 }
8680
8681
AddToMetadataInterfaceList(PVMFMetadataExtensionInterface * aMetadataIF,PVMFSessionId aSessionId,PVPlayerEngineDatapath * aEngineDatapath,PVMFNodeInterface * aNode)8682 PVMFStatus PVPlayerEngine::AddToMetadataInterfaceList(PVMFMetadataExtensionInterface* aMetadataIF, PVMFSessionId aSessionId, PVPlayerEngineDatapath* aEngineDatapath, PVMFNodeInterface* aNode)
8683 {
8684 // Validate the interface ptr
8685 if (aMetadataIF == NULL)
8686 {
8687 return PVMFErrArgument;
8688 }
8689
8690 // Add the specified interface ptr and session ID to the list
8691 PVPlayerEngineMetadataIFInfo mdifinfo;
8692 mdifinfo.iInterface = aMetadataIF;
8693 mdifinfo.iSessionId = aSessionId;
8694 mdifinfo.iEngineDatapath = aEngineDatapath;
8695 mdifinfo.iNode = aNode;
8696 int32 leavecode = 0;
8697 OSCL_TRY(leavecode, iMetadataIFList.push_back(mdifinfo));
8698 OSCL_FIRST_CATCH_ANY(leavecode, return PVMFErrNoMemory);
8699
8700 return PVMFSuccess;
8701 }
8702
RemoveFromMetadataInterfaceList(PVMFMetadataExtensionInterface * aMetadataIF,PVMFSessionId aSessionId)8703 PVMFStatus PVPlayerEngine::RemoveFromMetadataInterfaceList(PVMFMetadataExtensionInterface* aMetadataIF, PVMFSessionId aSessionId)
8704 {
8705 // Validate the interface ptr
8706 if (aMetadataIF == NULL)
8707 {
8708 return PVMFErrArgument;
8709 }
8710
8711 // Go through the list to find the specified entry
8712 for (uint32 i = 0; i < iMetadataIFList.size(); ++i)
8713 {
8714 if (aMetadataIF == iMetadataIFList[i].iInterface &&
8715 aSessionId == iMetadataIFList[i].iSessionId)
8716 {
8717 // Found it. Now erase it from the list
8718 iMetadataIFList.erase(iMetadataIFList.begin() + i);
8719 return PVMFSuccess;
8720 }
8721 }
8722
8723 // If here that means the specified entry wasn't found in the list
8724 return PVMFErrArgument;
8725 }
8726
8727
DoStop(PVPlayerEngineCommand & aCmd)8728 PVMFStatus PVPlayerEngine::DoStop(PVPlayerEngineCommand& aCmd)
8729 {
8730 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStop() In"));
8731
8732 if (GetPVPlayerState() == PVP_STATE_INITIALIZED)
8733 {
8734 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() Engine already in Initialized State"));
8735 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8736 return PVMFSuccess;
8737 }
8738
8739 if (GetPVPlayerState() != PVP_STATE_PREPARED &&
8740 GetPVPlayerState() != PVP_STATE_STARTED &&
8741 GetPVPlayerState() != PVP_STATE_PAUSED)
8742 {
8743 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() Wrong engine state"));
8744 return PVMFErrInvalidState;
8745 }
8746
8747 if (iReleaseMetadataValuesPending)
8748 {
8749 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
8750 (0, "PVPlayerEngine::DoStop() Wrong engine Usage, Stop called without releasing metadata values"));
8751 return PVMFErrReleaseMetadataValueNotDone;
8752 }
8753
8754 // reset the dataReady event boolean
8755 iDataReadySent = false;
8756
8757 // reset all repos related variables
8758 ResetReposVariables(true);
8759
8760 // Stop the playback position status timer
8761 StopPlaybackStatusTimer();
8762
8763 // Stop the playback clock
8764 iPlaybackClock.Stop();
8765 uint32 starttime = 0;
8766 bool overflow = 0;
8767 iPlaybackClock.SetStartTime32(starttime, PVMF_MEDIA_CLOCK_MSEC, overflow);
8768 iPlaybackDirection = 1;
8769
8770 // Reset the begin/end time variables
8771 iCurrentBeginPosition.iIndeterminate = true;
8772 iCurrentEndPosition.iIndeterminate = true;
8773 iQueuedBeginPosition.iIndeterminate = true;
8774 iQueuedEndPosition.iIndeterminate = true;
8775
8776 // Reset the paused-due-to-EOS flag
8777 iPlaybackPausedDueToEndOfClip = false;
8778
8779 // Stop the end time check
8780 if (iEndTimeCheckEnabled)
8781 {
8782 iEndTimeCheckEnabled = false;
8783 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
8784 }
8785
8786 PVMFStatus retval = PVMFErrNotSupported;
8787
8788 // Start the stopping sequence
8789 // First stop all the active datapaths
8790 iNumPendingDatapathCmd = 0;
8791 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8792 {
8793 if (iDatapathList[i].iDatapath)
8794 {
8795 PVMFStatus retcode = DoDatapathStop(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext());
8796 if (retcode == PVMFSuccess)
8797 {
8798 ++iNumPendingDatapathCmd;
8799 retval = PVMFSuccess;
8800 }
8801 else
8802 {
8803 retval = retcode;
8804 break;
8805 }
8806 }
8807 }
8808
8809 if (iNumPendingDatapathCmd == 0 && retval == PVMFErrNotSupported)
8810 {
8811 // If there are no active datapath, stop the source node
8812 retval = DoSourceNodeStop(aCmd.GetCmdId(), aCmd.GetContext());
8813 }
8814
8815 if (retval != PVMFSuccess)
8816 {
8817 bool ehPending = CheckForPendingErrorHandlingCmd();
8818 if (ehPending)
8819 {
8820 // there should be no error handling queued.
8821 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() Already EH pending, should never happen"));
8822 return PVMFPending;
8823 }
8824 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoStop() source node failed, go in Error handling, Add EH command"));
8825 iCommandCompleteStatusInErrorHandling = retval;
8826 iCommandCompleteErrMsgInErrorHandling = NULL;
8827
8828 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
8829 return PVMFPending;
8830 }
8831
8832 SetEngineState(PVP_ENGINE_STATE_STOPPING);
8833
8834 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoStop() Out"));
8835 return PVMFSuccess;
8836 }
8837
8838
DoDatapathStop(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)8839 PVMFStatus PVPlayerEngine::DoDatapathStop(PVPlayerEngineDatapath& aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
8840 {
8841 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStop() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
8842 if (aDatapath.iTrackInfo == NULL)
8843 {
8844 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathStop() TrackInfo not available, failure"));
8845 return PVMFFailure;
8846 }
8847
8848 // Stop the datapath
8849 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPStop);
8850
8851 PVMFStatus retval = aDatapath.iDatapath->Stop((OsclAny*)context);
8852 if (retval != PVMFSuccess)
8853 {
8854 FreeEngineContext(context);
8855 }
8856
8857 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathStop() Out"));
8858 return retval;
8859 }
8860
8861
DoSourceNodeStop(PVCommandId aCmdId,OsclAny * aCmdContext)8862 PVMFStatus PVPlayerEngine::DoSourceNodeStop(PVCommandId aCmdId, OsclAny* aCmdContext)
8863 {
8864 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStop() In"));
8865
8866 if (iSourceNode == NULL)
8867 {
8868 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStop() Source node not available."));
8869 return PVMFFailure;
8870 }
8871
8872 // Stop the source node
8873 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, -1);
8874
8875 PVMFCommandId cmdid = -1;
8876 int32 leavecode = 0;
8877 OSCL_TRY(leavecode, cmdid = iSourceNode->Stop(iSourceNodeSessionId, (OsclAny*)context));
8878 OSCL_FIRST_CATCH_ANY(leavecode,
8879 FreeEngineContext(context);
8880 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeStop() Stop on iSourceNode did a leave!"));
8881 return PVMFFailure);
8882
8883 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeStop() Out"));
8884
8885 return PVMFSuccess;
8886 }
8887
8888
DoDatapathTeardown(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)8889 PVMFStatus PVPlayerEngine::DoDatapathTeardown(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
8890 {
8891 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathTeardown() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
8892
8893 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPTeardown);
8894
8895 PVMFStatus retval = aDatapath.iDatapath->Teardown((OsclAny*)context);
8896 if (retval != PVMFSuccess)
8897 {
8898 FreeEngineContext(context);
8899 }
8900
8901 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathTeardown() Out"));
8902 return retval;
8903 }
8904
8905
DoDatapathReset(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)8906 PVMFStatus PVPlayerEngine::DoDatapathReset(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
8907 {
8908 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathReset() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
8909
8910 // Reset the datapath
8911 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, NULL, aDatapath.iDatapath, aCmdId, aCmdContext, PVP_CMD_DPReset);
8912
8913 PVMFStatus retval = aDatapath.iDatapath->Reset((OsclAny*)context);
8914 if (retval != PVMFSuccess)
8915 {
8916 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoDatapathReset() Reset failed. Asserting"));
8917 FreeEngineContext(context);
8918 OSCL_ASSERT(false);
8919 }
8920
8921 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoDatapathReset() Out"));
8922 return retval;
8923 }
8924
8925
DoRemoveDataSink(PVPlayerEngineCommand & aCmd)8926 PVMFStatus PVPlayerEngine::DoRemoveDataSink(PVPlayerEngineCommand& aCmd)
8927 {
8928 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSink() In"));
8929
8930 // previously removed, e.g. during error handling ?
8931 if (iDatapathList.empty() && GetPVPlayerState() == PVP_STATE_IDLE)
8932 {
8933 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSink() All sinks were previously deleted"));
8934 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8935 return PVMFSuccess;
8936 }
8937
8938 if (GetPVPlayerState() != PVP_STATE_INITIALIZED)
8939 {
8940 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSink() Wrong engine state"));
8941 return PVMFErrInvalidState;
8942 }
8943
8944 PVPlayerDataSink* datasink = (PVPlayerDataSink*)(aCmd.GetParam(0).pOsclAny_value);
8945
8946 if (datasink == NULL)
8947 {
8948 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSink() Passed in parameter invalid"));
8949 return PVMFErrArgument;
8950 }
8951
8952 // Find the track that the passed-in sink belongs to
8953 PVPlayerEngineDatapath* pvpedp = NULL;
8954 int32 dpindex = -1;
8955 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8956 {
8957 if (iDatapathList[i].iDataSink == datasink)
8958 {
8959 pvpedp = &(iDatapathList[i]);
8960 dpindex = i;
8961 break;
8962 }
8963 }
8964
8965 if (pvpedp == NULL || dpindex == -1)
8966 {
8967 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSink() Passed in data sink does not match with ones in engine"));
8968 return PVMFFailure;
8969 }
8970 else
8971 {
8972 // Cleanup and remove the datapath associated with the data sink from the list
8973 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoRemoveDataSink() Removing datapath"));
8974 DoEngineDatapathCleanup(*pvpedp);
8975
8976 iDatapathList.erase(iDatapathList.begin() + dpindex);
8977 }
8978
8979 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
8980
8981 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSink() Out"));
8982 return PVMFSuccess;
8983 }
8984
DoRemoveAllSinks()8985 void PVPlayerEngine::DoRemoveAllSinks()
8986 {
8987 // Clean up the datapaths
8988 for (uint32 i = 0; i < iDatapathList.size(); ++i)
8989 {
8990 DoEngineDatapathCleanup(iDatapathList[i]);
8991 }
8992 iDatapathList.clear();
8993 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoRemoveAllSinks() all datapaths removed"));
8994 }
8995
8996
DoReset(PVPlayerEngineCommand & aCmd)8997 PVMFStatus PVPlayerEngine::DoReset(PVPlayerEngineCommand& aCmd)
8998 {
8999 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReset() In"));
9000
9001 // set engine state to Resetting
9002 SetEngineState(PVP_ENGINE_STATE_RESETTING);
9003 iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
9004
9005 // reset all repos related variables
9006 ResetReposVariables(true);
9007
9008 // Stop the playback position status timer
9009 StopPlaybackStatusTimer();
9010
9011 // Stop the playback clock
9012 iPlaybackClock.Stop();
9013 uint32 starttime = 0;
9014 bool overflow = 0;
9015 iPlaybackClock.SetStartTime32(starttime, PVMF_MEDIA_CLOCK_MSEC, overflow);
9016 iPlaybackDirection = 1;
9017
9018 // Reset the begin/end time variables
9019 iCurrentBeginPosition.iIndeterminate = true;
9020 iCurrentEndPosition.iIndeterminate = true;
9021 iQueuedBeginPosition.iIndeterminate = true;
9022 iQueuedEndPosition.iIndeterminate = true;
9023
9024 // Reset the paused-due-to-EOS flag
9025 iPlaybackPausedDueToEndOfClip = false;
9026
9027 // Reset the Presentation Info list
9028 iSourcePresInfoList.Reset();
9029
9030 // Clear the Track selection List
9031 iTrackSelectionList.clear();
9032
9033 // Stop the end time check
9034 if (iEndTimeCheckEnabled)
9035 {
9036 iEndTimeCheckEnabled = false;
9037 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
9038 }
9039
9040 int32 leavecode = 0;
9041 PVMFStatus status = PVMFSuccess;
9042
9043 if (iSourceNode)
9044 {
9045 if (iSourceNode->GetState() != EPVMFNodeCreated)
9046 {
9047 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
9048
9049 PVMFCommandId cmdid = -1;
9050 leavecode = 0;
9051 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
9052 OSCL_FIRST_CATCH_ANY(leavecode,
9053
9054 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoReset() Reset on iSourceNode did a leave!"));
9055 FreeEngineContext(context);
9056 OSCL_ASSERT(false);
9057 return PVMFFailure);
9058 }
9059 else
9060 {
9061 // It is assumed that if SourceNode is in created state then datapaths if present,
9062 // has to be in IDLE State
9063 if (!iDatapathList.empty())
9064 {
9065 for (uint32 i = 0; i < iDatapathList.size(); ++i)
9066 {
9067 if (!iDatapathList[i].iDatapath)
9068 {
9069 if (iDatapathList[i].iDatapath->iState != PVPDP_IDLE)
9070 {
9071 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
9072 (0, "PVPlayerEngine::DoReset() Source Node already in created state, Datapath not in idle state, asserting"));
9073 OSCL_ASSERT(false);
9074 }
9075 }
9076 }
9077 DoRemoveAllSinks();
9078 }
9079 if (iDataSource)
9080 {
9081 RemoveDataSourceSync(*iDataSource);
9082 }
9083 SetEngineState(PVP_ENGINE_STATE_IDLE);
9084 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
9085 }
9086 }
9087 else
9088 {
9089 if (iDataSource)
9090 {
9091 RemoveDataSourceSync(*iDataSource);
9092 }
9093 SetEngineState(PVP_ENGINE_STATE_IDLE);
9094 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
9095 }
9096
9097 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoReset() Out"));
9098 return status;
9099 }
9100
RemoveDataSourceSync(PVPlayerDataSource & aSrc)9101 PVMFStatus PVPlayerEngine::RemoveDataSourceSync(PVPlayerDataSource &aSrc)
9102 {
9103 OSCL_UNUSED_ARG(aSrc);
9104
9105 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSourceSync() In"));
9106
9107 // Destroy the source node if present
9108 DoSourceNodeCleanup();
9109
9110 // Remove Stored KVP Values
9111 DeleteKVPValues();
9112
9113 // Remove all metadata IF from the list
9114 iMetadataIFList.clear();
9115
9116 iDataSource = NULL;
9117
9118 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::RemoveDataSourceSync() Out"));
9119 return PVMFSuccess;
9120 }
9121
9122
DoRemoveDataSource(PVPlayerEngineCommand & aCmd)9123 PVMFStatus PVPlayerEngine::DoRemoveDataSource(PVPlayerEngineCommand& aCmd)
9124 {
9125 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSource() In"));
9126
9127 if (GetPVPlayerState() != PVP_STATE_IDLE)
9128 {
9129 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSource() called when engine is not in the IDLE state"));
9130 return PVMFErrInvalidState;
9131 }
9132
9133 if (iDataSource == NULL) // previously removed, e.g. during errorhandling
9134 {
9135 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
9136 return PVMFSuccess;
9137 }
9138
9139 PVPlayerDataSource* src = (PVPlayerDataSource*)(aCmd.GetParam(0).pOsclAny_value);
9140
9141 if (iDataSource != src || src == NULL)
9142 {
9143 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoRemoveDataSource() Passed in parameter invalid"));
9144 return PVMFErrArgument;
9145 }
9146
9147 PVMFStatus result = RemoveDataSourceSync(*src);
9148
9149 if (result == PVMFSuccess)
9150 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
9151
9152 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoRemoveDataSource() Out"));
9153 return result;
9154 }
9155
9156
DoSourceUnderflowAutoPause(PVPlayerEngineCommand & aCmd)9157 PVMFStatus PVPlayerEngine::DoSourceUnderflowAutoPause(PVPlayerEngineCommand& aCmd)
9158 {
9159 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() In"));
9160
9161 /*
9162 * Underflow can happen in the following States
9163 * Prepared - Use-cases where-in Source Node reports DataReady and goes into
9164 * underflow immediately when it starts to retrieve data.
9165 * Started - This will be the most generic use-case where in the source node
9166 * is retreiving data and because of low bandwidth conditions runs out of data.
9167 * In such case Source Node will send an Underflow event to Engine.
9168 * Paused - A rare use-case but can happen. Use-case where Source Node is about
9169 * to run out of data and just before Source Node sends an Underflow event to
9170 * engine, user presses Pause on Engine. Engine gets Pause from user and Underflow
9171 * from Source Node back-to-back.
9172 */
9173 bool pauseSinkNodes = false;
9174
9175 switch (iState)
9176 {
9177 case PVP_ENGINE_STATE_PREPARED:
9178 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9179 (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() in Prepared state"));
9180 SetEngineState(PVP_ENGINE_STATE_AUTO_PAUSED);
9181 break;
9182
9183 case PVP_ENGINE_STATE_STARTED:
9184 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9185 (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() in Started state"));
9186 pauseSinkNodes = true;
9187 break;
9188
9189 case PVP_ENGINE_STATE_PAUSED:
9190 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9191 (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() in Paused state"));
9192 break;
9193
9194 default:
9195 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
9196 (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() Invalid state so cancel auto-pause request!"));
9197 return PVMFErrCancelled;
9198 }
9199
9200 // Stop the watchdog timer if active. We will Start the timer again in auto-resume.
9201 // this should only be done when engine is waiting for StartofData info event
9202 // after reposition.
9203 if (iNumPVMFInfoStartOfDataPending > 0)
9204 {
9205 if (iWatchDogTimer->IsBusy())
9206 {
9207 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
9208 (0, "PVPlayerEngine::DoSourceUnderflowAutoPause - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
9209 iWatchDogTimer->Cancel();
9210 }
9211 }
9212
9213 if (!pauseSinkNodes)
9214 {
9215 // Sink nodes already in Paused state or have no data to process, so
9216 // no need to call Pause on the sink nodes.
9217 return PVMFErrNotSupported;
9218 }
9219
9220 // Pause the playback clock
9221 iPlaybackClock.Pause();
9222
9223 uint32 i;
9224 // Notify data sinks that clock has paused
9225 for (i = 0; i < iDatapathList.size(); ++i)
9226 {
9227 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
9228 {
9229 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStopped();
9230 }
9231 }
9232
9233 PVMFStatus retval = PVMFErrNotSupported;
9234
9235 // Pause all active sink nodes
9236 iNumPendingDatapathCmd = 0;
9237 for (i = 0; i < iDatapathList.size(); ++i)
9238 {
9239 if (iDatapathList[i].iDatapath)
9240 {
9241 retval = DoSinkNodePause(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext());
9242 if (retval == PVMFSuccess)
9243 {
9244 ++iNumPendingDatapathCmd;
9245 }
9246 else
9247 {
9248 break;
9249 }
9250 }
9251 }
9252
9253 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceUnderflowAutoPause() Out"));
9254 if (iNumPendingDatapathCmd == 0)
9255 {
9256 return PVMFErrNotSupported;
9257 }
9258 else
9259 {
9260 SetEngineState(PVP_ENGINE_STATE_AUTO_PAUSING);
9261 return retval;
9262 }
9263 }
9264
9265
DoSourceDataReadyAutoResume(PVPlayerEngineCommand & aCmd)9266 PVMFStatus PVPlayerEngine::DoSourceDataReadyAutoResume(PVPlayerEngineCommand& aCmd)
9267 {
9268 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() In"));
9269
9270 // Don't need to worry about transitional states(...ING).
9271 // Auto-pause/resume cmds are just regular engine cmds and won't be interrupted by normal ones
9272
9273 // Check if Datapaths (Sink Node) are already in Started state.
9274 bool datapathSinkNodeStarted = false;
9275 for (uint32 j = 0; j < iDatapathList.size(); j++)
9276 {
9277 if (iDatapathList[j].iSinkNode)
9278 {
9279 if (iDatapathList[j].iSinkNode->GetState() != EPVMFNodeStarted)
9280 {
9281 // One of the nodes is not in Started state break from the loop
9282 // keeping the boolean datapathSinkNodeStaretd as false.
9283 datapathSinkNodeStarted = false;
9284 break;
9285 }
9286 // this will be true only when all Sink Nodes are in started state.
9287 datapathSinkNodeStarted = true;
9288 }
9289 }
9290
9291 // Next check to see if it is any one of the use-cases:
9292 // Prepare->Underflow->Start->DataReady or
9293 // Prepare->Underflow->DataReady->Start or
9294 // Underflow->Pause->Resume->DataReady or
9295 // Underflow->Pause->SetPlaybackRange->Resume->DataReady
9296 // These are cases where Sink Nodes are already in Started state and
9297 // engine might be still waiting for PVMFInfoStartOfData.
9298 // Here if all PVMFInfoStartofData have not been received yet,
9299 // then iNumPVMFInfoStartOfDataPending would be non-zero,
9300 // In few of these usecase, engine starts playback clock in Resume, source nodes are sposed to pause the
9301 // clock, since they are the ones in underflow. Once source nodes report dataready, engine would
9302 // already be in STARTED state. So if the clock is still paused, then start it here.
9303 // Here just send NotSupported so engine can send DataReady Event to the app.
9304 // and set the watchdog timer which was cancelled when underflow was recieved.
9305 if (datapathSinkNodeStarted)
9306 {
9307 if (iState == PVP_ENGINE_STATE_PREPARED)
9308 {
9309 // DataReady recieved during Prepare, Engine just needs to send
9310 // DataReady event.
9311 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9312 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: DataReady rcvd, Engine in Prepared state"));
9313 }
9314 else if (iState == PVP_ENGINE_STATE_STARTED)
9315 {
9316 // Usecases for this scenario:
9317 // Underflow->Pause->Resume->DataReady
9318 // Underflow->Pause->SetPlaybackRange->Resume->DataReady
9319 // Prepare->Underflow->Start->DataReady
9320 // do nothing here
9321 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9322 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: DataReady rcvd, Engine already in Started state"));
9323 }
9324 else if (iState == PVP_ENGINE_STATE_AUTO_PAUSED)
9325 {
9326 // Change state back to PREPARED, since Underflow and Dataready cancel each other out.
9327 // Wait for Start command from App to Start the clock and change state to STARTED.
9328 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9329 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: DataReady rcvd in PVP_ENGINE_STATE_AUTO_PAUSED state. Set state back to PREPARED."));
9330 SetEngineState(PVP_ENGINE_STATE_PREPARED);
9331 }
9332 else
9333 {
9334 // This should never happen
9335 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
9336 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() Invalid state %d, Sinks in Started state", iState));
9337 OSCL_ASSERT(false);
9338 }
9339
9340 if (iNumPVMFInfoStartOfDataPending > 0)
9341 {
9342 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
9343 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume: Clock in Stopped state, waiting for StartofData"));
9344
9345 if (iWatchDogTimerInterval > 0)
9346 {
9347 if (iWatchDogTimer->IsBusy())
9348 {
9349 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
9350 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
9351 iWatchDogTimer->Cancel();
9352 }
9353
9354 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
9355 (0, "PVPlayerEngine::DoSourceDataReadyAutoResume Setting WatchDogTimer for %d ms, iNumPVMFInfoStartOfDataPending=%d",
9356 iWatchDogTimerInterval, iNumPVMFInfoStartOfDataPending));
9357 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
9358 iWatchDogTimer->Start();
9359 }
9360 }
9361 else if ((iNumPVMFInfoStartOfDataPending == 0) && (iState == PVP_ENGINE_STATE_STARTED))
9362 {
9363 StartPlaybackClock();
9364
9365 // Notify data sinks that clock has started
9366 for (uint32 i = 0; i < iDatapathList.size(); ++i)
9367 {
9368 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
9369 {
9370 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
9371 }
9372 }
9373 }
9374 //return PVMFErrNotSupported so the the DataReady can be sent, depending on iDataReadySent flag.
9375 return PVMFErrNotSupported;
9376 }
9377
9378 // Next check to see if it is Underflow->Pause->DataReady->Resume usecase.
9379 // Then we CANNOT start clock in here, because clock is paused by app.
9380 // After Pause done, the engine is in PAUSED state. By allowing auto-resume only when
9381 // auto-paused we deal with this usecase ok.
9382 if (iState != PVP_ENGINE_STATE_AUTO_PAUSED)
9383 {
9384 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() Invalid state %d", iState));
9385 //return PVMFErrNotSupported so the the DataReady can be sent, depending on iDataReadySent flag.
9386 return PVMFErrNotSupported;
9387 }
9388
9389 PVMFStatus retval = PVMFErrNotSupported;
9390
9391 // Resume all active sink nodes
9392 iNumPendingDatapathCmd = 0;
9393 for (uint32 i = 0; i < iDatapathList.size(); ++i)
9394 {
9395 if (iDatapathList[i].iDatapath)
9396 {
9397 retval = DoSinkNodeResume(iDatapathList[i], aCmd.GetCmdId(), aCmd.GetContext());
9398 if (retval == PVMFSuccess)
9399 {
9400 ++iNumPendingDatapathCmd;
9401 }
9402 else
9403 {
9404 break;
9405 }
9406 }
9407 }
9408
9409 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceDataReadyAutoResume() Out"));
9410 if (iNumPendingDatapathCmd == 0)
9411 {
9412 return PVMFErrNotSupported;
9413 }
9414 else
9415 {
9416 SetEngineState(PVP_ENGINE_STATE_AUTO_RESUMING);
9417 return retval;
9418 }
9419 }
9420
9421
DoSinkNodePause(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)9422 PVMFStatus PVPlayerEngine::DoSinkNodePause(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
9423 {
9424 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodePause() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
9425
9426 if (!(aDatapath.iTrackInfo) || !(aDatapath.iSinkNode))
9427 {
9428 return PVMFErrNotSupported;
9429 }
9430
9431 // Pause the sink node
9432 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeAutoPause);
9433
9434 PVMFCommandId cmdid = -1;
9435 int32 leavecode = 0;
9436 OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->Pause(aDatapath.iSinkNodeSessionId, (OsclAny*)context));
9437 OSCL_FIRST_CATCH_ANY(leavecode,
9438 FreeEngineContext(context);
9439 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodePause() Pause on sink node did a leave!"));
9440 return PVMFFailure);
9441
9442 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodePause() Out"));
9443
9444 return PVMFSuccess;
9445 }
9446
9447
DoSinkNodeResume(PVPlayerEngineDatapath & aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext)9448 PVMFStatus PVPlayerEngine::DoSinkNodeResume(PVPlayerEngineDatapath &aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext)
9449 {
9450 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeResume() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
9451
9452 if (!(aDatapath.iTrackInfo) || !(aDatapath.iSinkNode))
9453 {
9454 return PVMFErrNotSupported;
9455 }
9456
9457 // Start the sink node to resume
9458 PVPlayerEngineContext* context = AllocateEngineContext(&aDatapath, aDatapath.iSinkNode, NULL, aCmdId, aCmdContext, PVP_CMD_SinkNodeAutoResume);
9459
9460 PVMFCommandId cmdid = -1;
9461 int32 leavecode = 0;
9462 OSCL_TRY(leavecode, cmdid = aDatapath.iSinkNode->Start(aDatapath.iSinkNodeSessionId, (OsclAny*)context));
9463 OSCL_FIRST_CATCH_ANY(leavecode,
9464 FreeEngineContext(context);
9465 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSinkNodeResume() Start on sink node did a leave!"));
9466 return PVMFFailure);
9467
9468 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeResume() Out"));
9469
9470 return PVMFSuccess;
9471 }
9472
DoEngineDatapathTeardown(PVPlayerEngineDatapath & aDatapath)9473 void PVPlayerEngine::DoEngineDatapathTeardown(PVPlayerEngineDatapath& aDatapath)
9474 {
9475 if (aDatapath.iTrackInfo)
9476 {
9477 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathTeardown() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
9478 }
9479 else
9480 {
9481 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathTeardown() In"));
9482 }
9483
9484 if (aDatapath.iDatapath)
9485 {
9486 // Shutdown and reset the datapath
9487 aDatapath.iDatapath->DisconnectNodeSession();
9488 aDatapath.iDatapath->SetSinkNode(NULL);
9489 aDatapath.iDatapath->SetDecNode(NULL);
9490 aDatapath.iDatapath->SetSourceNode(NULL);
9491 }
9492
9493 if (aDatapath.iSinkNode)
9494 {
9495 PVMFStatus status = PVMFFailure;
9496 status = aDatapath.iSinkNode->Disconnect(aDatapath.iSinkNodeSessionId);
9497 if (status == PVMFFailure)
9498 {
9499 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Disconnect on Sink Node Failed"));
9500 OSCL_ASSERT(false);
9501 }
9502 status = aDatapath.iSinkNode->ThreadLogoff();
9503 if (status == PVMFFailure)
9504 {
9505 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Threadlogoff on SinkNode Failed"));
9506 OSCL_ASSERT(false);
9507 }
9508
9509 // Remove sync ctrl IF if available
9510 if (aDatapath.iSinkNodeSyncCtrlIF)
9511 {
9512 aDatapath.iSinkNodeSyncCtrlIF->SetClock(NULL);
9513 aDatapath.iSinkNodeSyncCtrlIF->removeRef();
9514 aDatapath.iSinkNodeSyncCtrlIF = NULL;
9515 }
9516
9517 // Remove metadata IF if available
9518 if (aDatapath.iSinkNodeMetadataExtIF)
9519 {
9520 RemoveFromMetadataInterfaceList(aDatapath.iSinkNodeMetadataExtIF, aDatapath.iSinkNodeSessionId);
9521 aDatapath.iSinkNodeMetadataExtIF->removeRef();
9522 aDatapath.iSinkNodeMetadataExtIF = NULL;
9523 }
9524
9525 // Remove cap-config IF if available
9526 if (aDatapath.iSinkNodeCapConfigIF)
9527 {
9528 aDatapath.iSinkNodeCapConfigIF = NULL;
9529 }
9530
9531 if (aDatapath.iDataSink)
9532 {
9533 if (aDatapath.iDataSink->GetDataSinkType() == PVP_DATASINKTYPE_FILENAME)
9534 {
9535 // Remove file output config IF if available
9536 if (aDatapath.iSinkNodeFOConfigIF)
9537 {
9538 aDatapath.iSinkNodeFOConfigIF->removeRef();
9539 aDatapath.iSinkNodeFOConfigIF = NULL;
9540 }
9541 // Delete the sink node since engine created it.
9542 PVFileOutputNodeFactory::DeleteFileOutput(aDatapath.iSinkNode);
9543 }
9544 }
9545 aDatapath.iSinkNode = NULL;
9546 }
9547
9548 if (aDatapath.iDecNode)
9549 {
9550 // Remove metadata IF if available
9551 if (aDatapath.iDecNodeMetadataExtIF)
9552 {
9553 RemoveFromMetadataInterfaceList(aDatapath.iDecNodeMetadataExtIF, aDatapath.iDecNodeSessionId);
9554 aDatapath.iDecNodeMetadataExtIF->removeRef();
9555 aDatapath.iDecNodeMetadataExtIF = NULL;
9556 }
9557
9558 // Remove cap-config IF if available
9559 if (aDatapath.iDecNodeCapConfigIF)
9560 {
9561 aDatapath.iDecNodeCapConfigIF = NULL;
9562 }
9563
9564 PVMFStatus status = PVMFFailure;
9565 status = aDatapath.iDecNode->Disconnect(aDatapath.iDecNodeSessionId);
9566 if (status == PVMFFailure)
9567 {
9568 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Disconnect on dec node Failed"));
9569 OSCL_ASSERT(false);
9570 }
9571 status = aDatapath.iDecNode->ThreadLogoff();
9572 if (status == PVMFFailure)
9573 {
9574 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() ThreadLogoff on dec node Failed"));
9575 OSCL_ASSERT(false);
9576 }
9577
9578 // search for matching uuid entry in list of instantiated nodes
9579 PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
9580 for (; iter != iNodeUuids.end(); ++iter)
9581 if (iter->iNode == aDatapath.iDecNode)
9582 break;
9583
9584 if (iter != iNodeUuids.end())
9585 {
9586 bool release_status = false;
9587
9588 release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, aDatapath.iDecNode);
9589
9590 if (release_status == false)
9591 {
9592 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Factory returned false while releasing the decnode"));
9593 return;
9594 }
9595
9596 iNodeUuids.erase(iter);
9597 aDatapath.iDecNode = NULL;
9598 }
9599 else
9600 {
9601 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() decnode not found"));
9602 return;
9603 }
9604 }
9605
9606 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Out"));
9607 }
9608
9609
DoEngineDatapathCleanup(PVPlayerEngineDatapath & aDatapath)9610 void PVPlayerEngine::DoEngineDatapathCleanup(PVPlayerEngineDatapath& aDatapath)
9611 {
9612 if (aDatapath.iTrackInfo)
9613 {
9614 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathCleanup() In %s", aDatapath.iTrackInfo->getTrackMimeType().get_cstr()));
9615 }
9616 else
9617 {
9618 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathCleanup() In"));
9619 }
9620
9621 DoEngineDatapathTeardown(aDatapath);
9622
9623 // Destroy the datapath utility object instance
9624 if (aDatapath.iDatapath)
9625 {
9626 OSCL_DELETE(aDatapath.iDatapath);
9627 aDatapath.iDatapath = NULL;
9628 }
9629
9630 // Destroy the track info
9631 if (aDatapath.iTrackInfo)
9632 {
9633 OSCL_DELETE(aDatapath.iTrackInfo);
9634 aDatapath.iTrackInfo = NULL;
9635 }
9636
9637 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoEngineDatapathCleanup() Out"));
9638 }
9639
9640
DoSourceNodeCleanup(void)9641 void PVPlayerEngine::DoSourceNodeCleanup(void)
9642 {
9643 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeCleanup() In"));
9644
9645 if (iSourceNode)
9646 {
9647 // Remove reference to the parser node init interface if available
9648 if (iSourceNodeInitIF)
9649 {
9650 iSourceNodeInitIF->removeRef();
9651 iSourceNodeInitIF = NULL;
9652 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeInitIF Released"));
9653 }
9654
9655 // Remove reference to the parser node track sel interface if available
9656 if (iSourceNodeTrackSelIF)
9657 {
9658 iPlayableList.Reset();
9659 iPreferenceList.Reset();
9660 iSourceNodeTrackSelIF->removeRef();
9661 iSourceNodeTrackSelIF = NULL;
9662 iTrackSelectionHelper = NULL;
9663 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeTrackSelIF Released"));
9664 }
9665
9666 // Remove reference to the parser node track level info interface if available
9667 if (iSourceNodeTrackLevelInfoIF)
9668 {
9669 iSourceNodeTrackLevelInfoIF->removeRef();
9670 iSourceNodeTrackLevelInfoIF = NULL;
9671 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeTrackLevelInfoIF Released"));
9672 }
9673
9674 // Remove reference to the parser node position control interface if available
9675 if (iSourceNodePBCtrlIF)
9676 {
9677 iSourceNodePBCtrlIF->removeRef();
9678 iSourceNodePBCtrlIF = NULL;
9679 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodePBCtrlIF Released"));
9680 }
9681
9682 // Remove reference to the parser node direction control interface if available
9683 if (iSourceNodeDirCtrlIF)
9684 {
9685 iSourceNodeDirCtrlIF->removeRef();
9686 iSourceNodeDirCtrlIF = NULL;
9687 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeDirCtrlIF Released"));
9688 }
9689
9690 // Remove reference to the parser node metadata interface if available
9691 if (iSourceNodeMetadataExtIF)
9692 {
9693 RemoveFromMetadataInterfaceList(iSourceNodeMetadataExtIF, iSourceNodeSessionId);
9694 iSourceNodeMetadataExtIF->removeRef();
9695 iSourceNodeMetadataExtIF = NULL;
9696 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeMetadataExtIF Released"));
9697 }
9698
9699 // Reset the duration value retrieved from source
9700 iSourceDurationAvailable = false;
9701 iSourceDurationInMS = 0;
9702
9703 // Remove reference to the parser node cap-config interface if available
9704 if (iSourceNodeCapConfigIF)
9705 {
9706 iSourceNodeCapConfigIF->removeRef();
9707 iSourceNodeCapConfigIF = NULL;
9708 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNodeCapConfigIF Released"));
9709 }
9710
9711 if (iSourceNodeCPMLicenseIF)
9712 {
9713 iSourceNodeCPMLicenseIF->removeRef();
9714 iSourceNodeCPMLicenseIF = NULL;
9715 }
9716
9717 // Reset the Presentation Info list
9718 iSourcePresInfoList.Reset();
9719
9720 PVMFStatus status = PVMFFailure;
9721 status = iSourceNode->Disconnect(iSourceNodeSessionId);
9722 if (status == PVMFFailure)
9723 {
9724 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeCleanup() Disconnect Failed"));
9725 OSCL_ASSERT(false);
9726 }
9727 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - DisConnect Done"));
9728
9729 status = iSourceNode->ThreadLogoff();
9730 if (status == PVMFFailure)
9731 {
9732 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeCleanup() ThreadLogoff Failed"));
9733 OSCL_ASSERT(false);
9734 }
9735 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - ThreadLogoff Done"));
9736
9737 // search for matching uuid entry in list of instantiated nodes
9738 PVPlayerEngineUuidNodeMapping* iter = iNodeUuids.begin();
9739 for (; iter != iNodeUuids.end(); ++iter)
9740 if (iter->iNode == iSourceNode)
9741 break;
9742
9743 if (iter != iNodeUuids.end())
9744 {
9745 bool release_status = false;
9746
9747 release_status = iPlayerNodeRegistry.ReleaseNode(iter->iUuid, iSourceNode);
9748
9749 if (release_status == false)
9750 {
9751 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSourceNodeCleanup() Factory returned false while releasing the sourcenode"));
9752 return;
9753 }
9754
9755
9756 iNodeUuids.erase(iter);
9757 iSourceNode = NULL;
9758 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNode Delete Done"));
9759 }
9760 else
9761 {
9762 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::DoSourceNodeCleanup() - iSourceNode not found"));
9763 return;
9764 }
9765 }
9766
9767 // Cleanup the control varibles related to rate & direction changes.
9768 iPlaybackDirection_New = iPlaybackDirection;
9769 iOutsideTimebase_New = iOutsideTimebase;
9770 iPlaybackClockRate_New = iPlaybackClockRate;
9771 iChangeDirectionNPT.iIndeterminate = true;
9772 // Reset the flag that tracks pause-due-to-EOS
9773 iPlaybackPausedDueToEndOfClip = false;
9774
9775 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSourceNodeCleanup() Out"));
9776 }
9777
9778
DoCapConfigGetParametersSync(PvmiKeyType aIdentifier,PvmiKvp * & aParameters,int & aNumParamElements,PvmiCapabilityContext aContext)9779 PVMFStatus PVPlayerEngine::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
9780 {
9781 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() In"));
9782 OSCL_UNUSED_ARG(aContext);
9783
9784 // Initialize the output parameters
9785 aNumParamElements = 0;
9786 aParameters = NULL;
9787
9788 // Count the number of components and parameters in the key
9789 int compcount = pv_mime_string_compcnt(aIdentifier);
9790 // Retrieve the first component from the key string
9791 char* compstr = NULL;
9792 pv_mime_string_extract_type(0, aIdentifier, compstr);
9793
9794 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
9795 {
9796 // First component should be "x-pvmf" and there must
9797 // be at least two components to go past x-pvmf
9798 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Invalid key string"));
9799 return PVMFErrArgument;
9800 }
9801
9802 // Retrieve the second component from the key string
9803 pv_mime_string_extract_type(1, aIdentifier, compstr);
9804
9805 // First check if it is key string for engine ("player")
9806 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
9807 {
9808 // Key is for player
9809 if (compcount == 2)
9810 {
9811 // Since key is "x-pvmf/player" return all
9812 // nodes available at this level. Ignore attribute
9813 // since capability is only allowed
9814
9815 // Allocate memory for the KVP list
9816 aParameters = (PvmiKvp*)oscl_malloc(PVPLAYERCONFIG_BASE_NUMKEYS * sizeof(PvmiKvp));
9817 if (aParameters == NULL)
9818 {
9819 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
9820 return PVMFErrNoMemory;
9821 }
9822 oscl_memset(aParameters, 0, PVPLAYERCONFIG_BASE_NUMKEYS*sizeof(PvmiKvp));
9823 // Allocate memory for the key strings in each KVP
9824 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_BASE_NUMKEYS * PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
9825 if (memblock == NULL)
9826 {
9827 oscl_free(aParameters);
9828 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
9829 return PVMFErrNoMemory;
9830 }
9831 oscl_strset(memblock, 0, PVPLAYERCONFIG_BASE_NUMKEYS*PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
9832 // Assign the key string buffer to each KVP
9833 int32 j;
9834 for (j = 0; j < PVPLAYERCONFIG_BASE_NUMKEYS; ++j)
9835 {
9836 aParameters[j].key = memblock + (j * PVPLAYERCONFIG_KEYSTRING_SIZE);
9837 }
9838 // Copy the requested info
9839 for (j = 0; j < PVPLAYERCONFIG_BASE_NUMKEYS; ++j)
9840 {
9841 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/player/"), 14);
9842 oscl_strncat(aParameters[j].key, PVPlayerConfigBaseKeys[j].iString, oscl_strlen(PVPlayerConfigBaseKeys[j].iString));
9843 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6);
9844 switch (PVPlayerConfigBaseKeys[j].iType)
9845 {
9846 case PVMI_KVPTYPE_AGGREGATE:
9847 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING));
9848 break;
9849
9850 case PVMI_KVPTYPE_POINTER:
9851 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING));
9852 break;
9853
9854 case PVMI_KVPTYPE_VALUE:
9855 default:
9856 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING));
9857 break;
9858 }
9859 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9);
9860 switch (PVPlayerConfigBaseKeys[j].iValueType)
9861 {
9862 case PVMI_KVPVALTYPE_RANGE_INT32:
9863 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
9864 break;
9865
9866 case PVMI_KVPVALTYPE_KSV:
9867 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
9868 break;
9869
9870 case PVMI_KVPVALTYPE_CHARPTR:
9871 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
9872 break;
9873
9874 case PVMI_KVPVALTYPE_BOOL:
9875 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
9876 break;
9877
9878 case PVMI_KVPVALTYPE_UINT32:
9879 default:
9880 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
9881 break;
9882 }
9883 aParameters[j].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
9884 }
9885
9886 aNumParamElements = PVPLAYERCONFIG_BASE_NUMKEYS;
9887 }
9888 else
9889 {
9890 // Retrieve the third component from the key string
9891 pv_mime_string_extract_type(2, aIdentifier, compstr);
9892
9893 for (int32 engcomp3ind = 0; engcomp3ind < PVPLAYERCONFIG_BASE_NUMKEYS; ++engcomp3ind)
9894 {
9895 // Go through each engine component string at 3rd level
9896 if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigBaseKeys[engcomp3ind].iString)) >= 0)
9897 {
9898 if (engcomp3ind == PRODUCTINFO)
9899 {
9900 // "x-pvmf/player/productinfo"
9901 if (compcount == 3)
9902 {
9903 // Return list of product info. Ignore the
9904 // attribute since capability is only allowed
9905
9906 // Allocate memory for the KVP list
9907 aParameters = (PvmiKvp*)oscl_malloc(PVPLAYERCONFIG_PRODINFO_NUMKEYS * sizeof(PvmiKvp));
9908 if (aParameters == NULL)
9909 {
9910 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
9911 return PVMFErrNoMemory;
9912 }
9913 oscl_memset(aParameters, 0, PVPLAYERCONFIG_PRODINFO_NUMKEYS*sizeof(PvmiKvp));
9914 // Allocate memory for the key strings in each KVP
9915 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_PRODINFO_NUMKEYS * PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
9916 if (memblock == NULL)
9917 {
9918 oscl_free(aParameters);
9919 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
9920 return PVMFErrNoMemory;
9921 }
9922 oscl_strset(memblock, 0, PVPLAYERCONFIG_PRODINFO_NUMKEYS*PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
9923 // Assign the key string buffer to each KVP
9924 int32 j;
9925 for (j = 0; j < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++j)
9926 {
9927 aParameters[j].key = memblock + (j * PVPLAYERCONFIG_KEYSTRING_SIZE);
9928 }
9929 // Copy the requested info
9930 for (j = 0; j < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++j)
9931 {
9932 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/player/productinfo/"), 26);
9933 oscl_strncat(aParameters[j].key, PVPlayerConfigProdInfoKeys[j].iString, oscl_strlen(PVPlayerConfigProdInfoKeys[j].iString));
9934 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type=value;valtype=char*"), 25);
9935 aParameters[j].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
9936 }
9937
9938 aNumParamElements = PVPLAYERCONFIG_PRODINFO_NUMKEYS;
9939 }
9940 else if (compcount == 4)
9941 {
9942 // Retrieve the fourth component from the key string
9943 pv_mime_string_extract_type(3, aIdentifier, compstr);
9944
9945 for (int32 engcomp4ind = 0; engcomp4ind < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++engcomp4ind)
9946 {
9947 if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigProdInfoKeys[engcomp4ind].iString)) >= 0)
9948 {
9949 // Determine what is requested
9950 PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
9951 if (reqattr == PVMI_KVPATTR_UNKNOWN)
9952 {
9953 // Default is current setting
9954 reqattr = PVMI_KVPATTR_CUR;
9955 }
9956
9957 // Return the requested info
9958 PVMFStatus retval = DoGetPlayerProductInfoParameter(aParameters, aNumParamElements, engcomp4ind, reqattr);
9959 if (retval != PVMFSuccess)
9960 {
9961 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Retrieving product info failed"));
9962 return retval;
9963 }
9964
9965 // Break out of the for(engcomp4ind) loop
9966 break;
9967 }
9968 }
9969 }
9970 else
9971 {
9972 // Right now engine doesn't support more than 4 components
9973 // so error out
9974 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Unsupported key"));
9975 return PVMFErrArgument;
9976 }
9977 }
9978 else
9979 {
9980 if (compcount == 3)
9981 {
9982 // Determine what is requested
9983 PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
9984 if (reqattr == PVMI_KVPATTR_UNKNOWN)
9985 {
9986 reqattr = PVMI_KVPATTR_CUR;
9987 }
9988
9989 // Return the requested info
9990 PVMFStatus retval = DoGetPlayerParameter(aParameters, aNumParamElements, engcomp3ind, reqattr);
9991 if (retval != PVMFSuccess)
9992 {
9993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Retrieving player parameter failed"));
9994 return retval;
9995 }
9996 }
9997 else
9998 {
9999 // Right now engine doesn't support more than 3 components
10000 // for this sub-key string so error out
10001 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Unsupported key"));
10002 return PVMFErrArgument;
10003 }
10004 }
10005
10006 // Breakout of the for(engcomp3ind) loop
10007 break;
10008 }
10009 }
10010 }
10011 }
10012 else
10013 {
10014 PVMFStatus retval = PVMFFailure;
10015
10016 // Go through each datapath's cap-config IF in the datapath list and check for the string.
10017 for (uint32 i = 0; i < iDatapathList.size(); i++)
10018 {
10019 if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
10020 {
10021 retval = iDatapathList[i].iDecNodeCapConfigIF->getParametersSync(NULL, aIdentifier, aParameters, aNumParamElements, aContext);
10022 if (retval == PVMFSuccess)
10023 {
10024 // Key matched break the loop.
10025 break;
10026 }
10027 }
10028
10029 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
10030 {
10031 retval = iDatapathList[i].iSinkNodeCapConfigIF->getParametersSync(NULL, aIdentifier, aParameters, aNumParamElements, aContext);
10032 if (retval == PVMFSuccess)
10033 {
10034 // Key matched break the loop.
10035 break;
10036 }
10037 }
10038 }
10039
10040 if (retval != PVMFSuccess)
10041 {
10042 return retval;
10043 }
10044 }
10045
10046 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Out"));
10047 if (aNumParamElements == 0)
10048 {
10049 // If no one could get the parameter, return error
10050 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigGetParametersSync() Unsupported key"));
10051 return PVMFFailure;
10052 }
10053 else
10054 {
10055 return PVMFSuccess;
10056 }
10057 }
10058
10059
DoCapConfigReleaseParameters(PvmiKvp * aParameters,int aNumElements)10060 PVMFStatus PVPlayerEngine::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements)
10061 {
10062 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() In"));
10063
10064 if (aParameters == NULL || aNumElements < 1)
10065 {
10066 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0"));
10067 return PVMFErrArgument;
10068 }
10069
10070 // Count the number of components and parameters in the key
10071 int compcount = pv_mime_string_compcnt(aParameters[0].key);
10072 // Retrieve the first component from the key string
10073 char* compstr = NULL;
10074 pv_mime_string_extract_type(0, aParameters[0].key, compstr);
10075
10076 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
10077 {
10078 // First component should be "x-pvmf" and there must
10079 // be at least two components to go past x-pvmf
10080 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() Unsupported key"));
10081 return PVMFErrArgument;
10082 }
10083
10084 // Retrieve the second component from the key string
10085 pv_mime_string_extract_type(1, aParameters[0].key, compstr);
10086
10087 // Assume all the parameters come from the same component so the base components are the same
10088 // First check if it is key string for engine ("player")
10089 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
10090 {
10091 // Go through each KVP and release memory for value if allocated from heap
10092 for (int32 i = 0; i < aNumElements; ++i)
10093 {
10094 // Next check if it is a value type that allocated memory
10095 PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key);
10096 if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
10097 {
10098 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key);
10099 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
10100 {
10101 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() Valtype not specified in key string"));
10102 return PVMFErrArgument;
10103 }
10104
10105 if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
10106 {
10107 oscl_free(aParameters[i].value.pChar_value);
10108 aParameters[i].value.pChar_value = NULL;
10109 }
10110 else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL)
10111 {
10112 oscl_free(aParameters[i].value.key_specific_value);
10113 aParameters[i].value.key_specific_value = NULL;
10114 }
10115 else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_INT32 && aParameters[i].value.key_specific_value != NULL)
10116 {
10117 range_int32* ri32 = (range_int32*)aParameters[i].value.key_specific_value;
10118 aParameters[i].value.key_specific_value = NULL;
10119 oscl_free(ri32);
10120 }
10121 else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL)
10122 {
10123 range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value;
10124 aParameters[i].value.key_specific_value = NULL;
10125 oscl_free(rui32);
10126 }
10127 // @TODO Add more types if engine starts returning more types
10128 }
10129 }
10130
10131 // Player engine allocated its key strings in one chunk so just free the first key string ptr
10132 oscl_free(aParameters[0].key);
10133
10134 // Free memory for the parameter list
10135 oscl_free(aParameters);
10136 aParameters = NULL;
10137 }
10138 else
10139 {
10140 PVMFStatus retval = PVMFFailure;
10141
10142 // Go through each datapath's cap-config IF in the datapath list and check for the string.
10143 for (uint32 i = 0; i < iDatapathList.size(); i++)
10144 {
10145 if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
10146 {
10147 retval = iDatapathList[i].iDecNodeCapConfigIF->releaseParameters(NULL, aParameters, aNumElements);
10148 if (retval == PVMFSuccess)
10149 {
10150 // Key matched break the loop.
10151 break;
10152 }
10153 }
10154
10155 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
10156 {
10157 retval = iDatapathList[i].iSinkNodeCapConfigIF->releaseParameters(NULL, aParameters, aNumElements);
10158 if (retval == PVMFSuccess)
10159 {
10160 // Key matched break the loop.
10161 break;
10162 }
10163 }
10164 }
10165
10166 if (retval != PVMFSuccess)
10167 {
10168 return retval;
10169 }
10170 }
10171
10172 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigReleaseParameters() Out"));
10173 return PVMFSuccess;
10174 }
10175
10176
DoCapConfigSetParameters(PVPlayerEngineCommand & aCmd,bool aSyncCmd)10177 PVMFStatus PVPlayerEngine::DoCapConfigSetParameters(PVPlayerEngineCommand& aCmd, bool aSyncCmd)
10178 {
10179 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigSetParameters() In"));
10180
10181 PvmiKvp* paramkvp;
10182 int32 numparam;
10183 PvmiKvp** retkvp;
10184 paramkvp = (PvmiKvp*)(aCmd.GetParam(0).pOsclAny_value);
10185 numparam = aCmd.GetParam(1).int32_value;
10186 retkvp = (PvmiKvp**)(aCmd.GetParam(2).pOsclAny_value);
10187
10188 if (paramkvp == NULL || retkvp == NULL || numparam < 1)
10189 {
10190 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Passed in parameter invalid"));
10191 return PVMFErrArgument;
10192 }
10193
10194 // Go through each parameter
10195 for (int32 paramind = 0; paramind < numparam; ++paramind)
10196 {
10197 if (iRollOverState == RollOverStateIdle)
10198 {
10199 PVMFStatus ret = VerifyAndSaveKVPValues(¶mkvp[paramind]);
10200 if (ret != PVMFSuccess)
10201 {
10202 return ret;
10203 };
10204 }
10205 // Count the number of components and parameters in the key
10206 int compcount = pv_mime_string_compcnt(paramkvp[paramind].key);
10207 // Retrieve the first component from the key string
10208 char* compstr = NULL;
10209 pv_mime_string_extract_type(0, paramkvp[paramind].key, compstr);
10210
10211 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
10212 {
10213 // First component should be "x-pvmf" and there must
10214 // be at least two components to go past x-pvmf
10215 *retkvp = ¶mkvp[paramind];
10216 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Unsupported key"));
10217 return PVMFErrArgument;
10218 }
10219
10220 // Retrieve the second component from the key string
10221 pv_mime_string_extract_type(1, paramkvp[paramind].key, compstr);
10222
10223 // First check if it is key string for engine ("player")
10224 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
10225 {
10226 if (compcount == 3)
10227 {
10228 // Verify and set the passed-in player setting
10229 PVMFStatus retval = DoVerifyAndSetPlayerParameter(paramkvp[paramind], true);
10230 if (retval != PVMFSuccess)
10231 {
10232 *retkvp = ¶mkvp[paramind];
10233 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
10234 return retval;
10235 }
10236 }
10237 else if (compcount == 4)
10238 {
10239 // Only product info keys have four components
10240 // Verify and set the passed-in product info setting
10241 PVMFStatus retval = DoVerifyAndSetPlayerProductInfoParameter(paramkvp[paramind], true);
10242 if (retval != PVMFSuccess)
10243 {
10244 *retkvp = ¶mkvp[paramind];
10245 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
10246 return retval;
10247 }
10248 }
10249 else
10250 {
10251 // Do not support more than 4 components right now
10252 *retkvp = ¶mkvp[paramind];
10253 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigSetParameters() Unsupported key"));
10254 return PVMFErrArgument;
10255 }
10256 }
10257 else
10258 {
10259 *retkvp = ¶mkvp[paramind];
10260 bool anysuccess = false;
10261
10262
10263 if (iSourceNodeCapConfigIF != NULL)
10264 {
10265 *retkvp = NULL;
10266 iSourceNodeCapConfigIF->setParametersSync(NULL, ¶mkvp[paramind], 1, *retkvp);
10267 if (*retkvp == NULL)
10268 {
10269 anysuccess = true;
10270 }
10271 }
10272 // Go through each datapath's cap-config IF in the datapath list and check for the string.
10273 for (uint32 i = 0; i < iDatapathList.size(); i++)
10274 {
10275 if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
10276 {
10277 *retkvp = NULL;
10278 iDatapathList[i].iDecNodeCapConfigIF->setParametersSync(NULL, ¶mkvp[paramind], 1, *retkvp);
10279 if (*retkvp == NULL)
10280 {
10281 anysuccess = true;
10282 break;
10283 }
10284 }
10285
10286 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
10287 {
10288 *retkvp = NULL;
10289 iDatapathList[i].iSinkNodeCapConfigIF->setParametersSync(NULL, ¶mkvp[paramind], 1, *retkvp);
10290 if (*retkvp == NULL)
10291 {
10292 anysuccess = true;
10293 break;
10294 }
10295 }
10296 }
10297
10298 if (anysuccess == false)
10299 {
10300 // setParametersSync was not accepted by the node(s)
10301 *retkvp = ¶mkvp[paramind];
10302 return PVMFErrArgument;
10303 }
10304 }
10305
10306 }
10307
10308 if (!aSyncCmd)
10309 {
10310 EngineCommandCompleted(aCmd.GetCmdId(), aCmd.GetContext(), PVMFSuccess);
10311 }
10312
10313 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigSetParameters() Out"));
10314 return PVMFSuccess;
10315 }
10316
10317
DoCapConfigVerifyParameters(PvmiKvp * aParameters,int aNumElements)10318 PVMFStatus PVPlayerEngine::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
10319 {
10320 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() In"));
10321
10322 if (aParameters == NULL || aNumElements < 1)
10323 {
10324 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Passed in parameter invalid"));
10325 return PVMFErrArgument;
10326 }
10327
10328 // Go through each parameter and verify
10329 for (int32 paramind = 0; paramind < aNumElements; ++paramind)
10330 {
10331 // Count the number of components and parameters in the key
10332 int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
10333 // Retrieve the first component from the key string
10334 char* compstr = NULL;
10335 pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
10336
10337 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
10338 {
10339 // First component should be "x-pvmf" and there must
10340 // be at least two components to go past x-pvmf
10341 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Unsupported key"));
10342 return PVMFErrArgument;
10343 }
10344
10345 // Retrieve the second component from the key string
10346 pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
10347
10348 // First check if it is key string for engine ("player")
10349 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("player")) >= 0)
10350 {
10351 if (compcount == 3)
10352 {
10353 // Verify the passed-in player setting
10354 PVMFStatus retval = DoVerifyAndSetPlayerParameter(aParameters[paramind], false);
10355 if (retval != PVMFSuccess)
10356 {
10357 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
10358 return retval;
10359 }
10360 }
10361 else if (compcount == 4)
10362 {
10363 // Only product info keys have four components
10364 // Verify the passed-in product info setting
10365 PVMFStatus retval = DoVerifyAndSetPlayerProductInfoParameter(aParameters[paramind], false);
10366 if (retval != PVMFSuccess)
10367 {
10368 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
10369 return retval;
10370 }
10371 }
10372 else
10373 {
10374 // Do not support more than 4 components right now
10375 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Unsupported key"));
10376 return PVMFErrArgument;
10377 }
10378 }
10379 else
10380 {
10381 PVMFStatus retval = PVMFFailure;
10382
10383 // Go through each datapath's cap-config IF in the datapath list and check for the string.
10384 for (uint32 i = 0; i < iDatapathList.size(); i++)
10385 {
10386 if (iDatapathList[i].iDecNodeCapConfigIF != NULL)
10387 {
10388 retval = iDatapathList[i].iDecNodeCapConfigIF->verifyParametersSync(NULL, &aParameters[paramind], 1);
10389 if (retval == PVMFSuccess)
10390 {
10391 // Key matched break the loop.
10392 break;
10393 }
10394 }
10395
10396 if (iDatapathList[i].iSinkNodeCapConfigIF != NULL)
10397 {
10398 retval = iDatapathList[i].iSinkNodeCapConfigIF->verifyParametersSync(NULL, &aParameters[paramind], 1);
10399 if (retval == PVMFSuccess)
10400 {
10401 // Key matched break the loop.
10402 break;
10403 }
10404 }
10405 }
10406
10407 if (retval != PVMFSuccess)
10408 {
10409 return retval;
10410 }
10411 }
10412 }
10413
10414 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Out"));
10415 return PVMFSuccess;
10416 }
10417
DoGetPlayerParameter(PvmiKvp * & aParameters,int & aNumParamElements,int32 aIndex,PvmiKvpAttr reqattr)10418 PVMFStatus PVPlayerEngine::DoGetPlayerParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
10419 {
10420 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerParameter() In"));
10421
10422 aNumParamElements = 0;
10423
10424 // Allocate memory for the KVP
10425 aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
10426 if (aParameters == NULL)
10427 {
10428 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for KVP failed"));
10429 return PVMFErrNoMemory;
10430 }
10431 oscl_memset(aParameters, 0, sizeof(PvmiKvp));
10432 // Allocate memory for the key string in KVP
10433 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
10434 if (memblock == NULL)
10435 {
10436 oscl_free(aParameters);
10437 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for key string failed"));
10438 return PVMFErrNoMemory;
10439 }
10440 oscl_strset(memblock, 0, PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
10441 // Assign the key string buffer to KVP
10442 aParameters[0].key = memblock;
10443
10444 // Copy the key string
10445 oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/player/"), 14);
10446 oscl_strncat(aParameters[0].key, PVPlayerConfigBaseKeys[aIndex].iString, oscl_strlen(PVPlayerConfigBaseKeys[aIndex].iString));
10447 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
10448 switch (PVPlayerConfigBaseKeys[aIndex].iValueType)
10449 {
10450 case PVMI_KVPVALTYPE_RANGE_INT32:
10451 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
10452 break;
10453
10454 case PVMI_KVPVALTYPE_KSV:
10455 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
10456 break;
10457
10458 case PVMI_KVPVALTYPE_CHARPTR:
10459 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
10460 break;
10461
10462 case PVMI_KVPVALTYPE_BOOL:
10463 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
10464 break;
10465
10466 case PVMI_KVPVALTYPE_UINT32:
10467 default:
10468 if (reqattr == PVMI_KVPATTR_CAP)
10469 {
10470 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
10471 }
10472 else
10473 {
10474 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
10475 }
10476 break;
10477 }
10478 aParameters[0].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
10479
10480 // Copy the requested info
10481 switch (aIndex)
10482 {
10483 case PBPOS_UNITS: // "pbpops_units"
10484 if (reqattr == PVMI_KVPATTR_CUR)
10485 {
10486 // Return current value
10487 // Allocate memory for the string
10488 char* curstr = (char*)oscl_malloc(32 * sizeof(char));
10489 if (curstr == NULL)
10490 {
10491 oscl_free(aParameters[0].key);
10492 oscl_free(aParameters);
10493 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for char* string failed"));
10494 return PVMFErrNoMemory;
10495 }
10496 oscl_strset(curstr, 0, 32);
10497 // Copy the appropriate string based on units being used
10498 switch (iPBPosStatusUnit)
10499 {
10500 case PVPPBPOSUNIT_SEC:
10501 oscl_strncpy(curstr, _STRLIT_CHAR("PVPPBPOSUNIT_SEC"), 16);
10502 aParameters[0].length = 16;
10503 break;
10504
10505 case PVPPBPOSUNIT_MIN:
10506 oscl_strncpy(curstr, _STRLIT_CHAR("PVPPBPOSUNIT_MIN"), 16);
10507 aParameters[0].length = 16;
10508 break;
10509
10510 case PVPPBPOSUNIT_MILLISEC:
10511 default:
10512 oscl_strncpy(curstr, _STRLIT_CHAR("PVPPBPOSUNIT_MILLISEC"), 21);
10513 aParameters[0].length = 21;
10514 break;
10515 }
10516
10517 aParameters[0].value.pChar_value = curstr;
10518 aParameters[0].capacity = 32;
10519 }
10520 else if (reqattr == PVMI_KVPATTR_DEF)
10521 {
10522 // Return default
10523 // Allocate memory for the string
10524 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_CONFIG_PBPOSSTATUSUNIT_DEF_STRING);
10525 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
10526 if (defstr == NULL)
10527 {
10528 oscl_free(aParameters[0].key);
10529 oscl_free(aParameters);
10530 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for char* string failed"));
10531 return PVMFErrNoMemory;
10532 }
10533 // Copy and set
10534 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_CONFIG_PBPOSSTATUSUNIT_DEF_STRING), defstrlen);
10535 defstr[defstrlen] = 0;
10536 aParameters[0].value.pChar_value = defstr;
10537 aParameters[0].capacity = defstrlen + 1;
10538 aParameters[0].length = defstrlen;
10539 }
10540 else
10541 {
10542 // Return capability
10543 // Allocate memory for the string
10544 int32 capstrlen = oscl_strlen(PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_CAP_STRING);
10545 char* capstr = (char*)oscl_malloc((capstrlen + 1) * sizeof(char));
10546 if (capstr == NULL)
10547 {
10548 oscl_free(aParameters[0].key);
10549 oscl_free(aParameters);
10550 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for char* string failed"));
10551 return PVMFErrNoMemory;
10552 }
10553 // Copy and set
10554 oscl_strncpy(capstr, _STRLIT_CHAR(PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_CAP_STRING), capstrlen);
10555 capstr[capstrlen] = 0;
10556 aParameters[0].value.pChar_value = capstr;
10557 aParameters[0].capacity = capstrlen + 1;
10558 aParameters[0].length = capstrlen;
10559 }
10560 break;
10561
10562 case PBPOS_INTERVAL: // "pbpos_interval"
10563 if (reqattr == PVMI_KVPATTR_CUR)
10564 {
10565 // Return current value
10566 aParameters[0].value.uint32_value = iPBPosStatusInterval;
10567 }
10568 else if (reqattr == PVMI_KVPATTR_DEF)
10569 {
10570 // Return default
10571 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_DEF;
10572 }
10573 else
10574 {
10575 // Return capability
10576 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
10577 if (rui32 == NULL)
10578 {
10579 oscl_free(aParameters[0].key);
10580 oscl_free(aParameters);
10581 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
10582 return PVMFErrNoMemory;
10583 }
10584 rui32->min = PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MIN;
10585 rui32->max = PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MAX;
10586 aParameters[0].value.key_specific_value = (void*)rui32;
10587 }
10588 break;
10589
10590 case ENDTIMECHECK_INTERVAL: // "endtimecheck_interval"
10591 if (reqattr == PVMI_KVPATTR_CUR)
10592 {
10593 // Return current value
10594 aParameters[0].value.uint32_value = iEndTimeCheckInterval;
10595 }
10596 else if (reqattr == PVMI_KVPATTR_DEF)
10597 {
10598 // Return default
10599 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_DEF;
10600 }
10601 else
10602 {
10603 // Return capability
10604 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
10605 if (rui32 == NULL)
10606 {
10607 oscl_free(aParameters[0].key);
10608 oscl_free(aParameters);
10609 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
10610 return PVMFErrNoMemory;
10611 }
10612 rui32->min = PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MIN;
10613 rui32->max = PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MAX;
10614 aParameters[0].value.key_specific_value = (void*)rui32;
10615 }
10616 break;
10617
10618 case SEEKTOSYNCPOINT: // "seektosyncpoint"
10619 if (reqattr == PVMI_KVPATTR_CUR)
10620 {
10621 // Return current value
10622 aParameters[0].value.bool_value = iSeekToSyncPoint;
10623 }
10624 else if (reqattr == PVMI_KVPATTR_DEF)
10625 {
10626 // Return default
10627 aParameters[0].value.bool_value = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINT_DEF;
10628 }
10629 else
10630 {
10631 // Return capability
10632 // Bool so no capability
10633 }
10634 break;
10635
10636 case SKIPTOREQUESTEDPOSITION: // "skiptorequestedpos"
10637 if (reqattr == PVMI_KVPATTR_CUR)
10638 {
10639 // Return current value
10640 aParameters[0].value.bool_value = iSkipToRequestedPosition;
10641 }
10642 else if (reqattr == PVMI_KVPATTR_DEF)
10643 {
10644 // Return default
10645 aParameters[0].value.bool_value = PVPLAYERENGINE_CONFIG_SKIPTOREQUESTEDPOS_DEF;
10646 }
10647 else
10648 {
10649 // Return capability
10650 // Bool so no capability
10651 }
10652 break;
10653
10654 case SYNCPOINTSEEKWINDOW: // "syncpointseekwindow"
10655 if (reqattr == PVMI_KVPATTR_CUR)
10656 {
10657 // Return current value
10658 aParameters[0].value.uint32_value = iSyncPointSeekWindow;
10659 }
10660 else if (reqattr == PVMI_KVPATTR_DEF)
10661 {
10662 // Return default
10663 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_DEF;
10664 }
10665 else
10666 {
10667 // Return capability
10668 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
10669 if (rui32 == NULL)
10670 {
10671 oscl_free(aParameters[0].key);
10672 oscl_free(aParameters);
10673 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
10674 return PVMFErrNoMemory;
10675 }
10676 rui32->min = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_MIN;
10677 rui32->max = PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_MAX;
10678 aParameters[0].value.key_specific_value = (void*)rui32;
10679 }
10680 break;
10681
10682 case SYNCMARGIN_VIDEO: // "syncmargin_video"
10683 case SYNCMARGIN_AUDIO: // "syncmargin_audio"
10684 case SYNCMARGIN_TEXT: // "syncmargin_text"
10685 {
10686 range_int32* ri32 = (range_int32*)oscl_malloc(sizeof(range_int32));
10687 if (ri32 == NULL)
10688 {
10689 oscl_free(aParameters[0].key);
10690 oscl_free(aParameters);
10691 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range int32 failed"));
10692 return PVMFErrNoMemory;
10693 }
10694
10695 if (reqattr == PVMI_KVPATTR_CUR)
10696 {
10697 // Return current value
10698 if (aIndex == SYNCMARGIN_VIDEO)
10699 {
10700 // Video
10701 ri32->min = iSyncMarginVideo.min;
10702 ri32->max = iSyncMarginVideo.max;
10703 }
10704 else if (aIndex == SYNCMARGIN_AUDIO)
10705 {
10706 // Audio
10707 ri32->min = iSyncMarginAudio.min;
10708 ri32->max = iSyncMarginAudio.max;
10709 }
10710 else
10711 {
10712 // Text
10713 ri32->min = iSyncMarginText.min;
10714 ri32->max = iSyncMarginText.max;
10715 }
10716 aParameters[0].value.key_specific_value = (void*)ri32;
10717 }
10718 else if (reqattr == PVMI_KVPATTR_DEF)
10719 {
10720 // Return default
10721 ri32->min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_EARLY_DEF;
10722 ri32->max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_LATE_DEF;
10723 aParameters[0].value.key_specific_value = (void*)ri32;
10724 }
10725 else
10726 {
10727 // Return capability
10728 ri32->min = PVPLAYERENGINE_CONFIG_SYNCMARGIN_MIN;
10729 ri32->max = PVPLAYERENGINE_CONFIG_SYNCMARGIN_MAX;
10730 aParameters[0].value.key_specific_value = (void*)ri32;
10731 }
10732 }
10733 break;
10734
10735 case NODECMD_TIMEOUT: // "nodecmd_timeout"
10736 if (reqattr == PVMI_KVPATTR_CUR)
10737 {
10738 // Return current value
10739 aParameters[0].value.uint32_value = iNodeCmdTimeout;
10740 }
10741 else if (reqattr == PVMI_KVPATTR_DEF)
10742 {
10743 // Return default
10744 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_DEF;
10745 }
10746 else
10747 {
10748 // Return capability
10749 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
10750 if (rui32 == NULL)
10751 {
10752 oscl_free(aParameters[0].key);
10753 oscl_free(aParameters);
10754 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32 failed"));
10755 return PVMFErrNoMemory;
10756 }
10757 rui32->min = PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MIN;
10758 rui32->max = PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MAX;
10759 aParameters[0].value.key_specific_value = (void*)rui32;
10760 }
10761 break;
10762
10763 case NODEDATAQUEIUING_TIMEOUT: // "nodedataqueuing_timeout"
10764 if (reqattr == PVMI_KVPATTR_CUR)
10765 {
10766 // Return current value
10767 aParameters[0].value.uint32_value = iNodeDataQueuingTimeout;
10768 }
10769 else if (reqattr == PVMI_KVPATTR_DEF)
10770 {
10771 // Return default
10772 aParameters[0].value.uint32_value = PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_DEF;
10773 }
10774 else
10775 {
10776 // Return capability
10777 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
10778 if (rui32 == NULL)
10779 {
10780 oscl_free(aParameters[0].key);
10781 oscl_free(aParameters);
10782 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Memory allocation for range uint32"));
10783 return PVMFErrNoMemory;
10784 }
10785 rui32->min = PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MIN;
10786 rui32->max = PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MAX;
10787 aParameters[0].value.key_specific_value = (void*)rui32;
10788 }
10789 break;
10790
10791 case PBPOS_ENABLE: // "pbpos_enable"
10792 if (reqattr == PVMI_KVPATTR_CUR)
10793 {
10794 // Return current value
10795 aParameters[0].value.bool_value = iPBPosEnable;
10796 }
10797 else if (reqattr == PVMI_KVPATTR_DEF)
10798 {
10799 // Return default
10800 aParameters[0].value.bool_value = true;
10801 }
10802 else
10803 {
10804 // Return capability
10805 // Bool so no capability
10806 }
10807 break;
10808 default:
10809 // Invalid index
10810 oscl_free(aParameters[0].key);
10811 oscl_free(aParameters);
10812 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Invalid index to player parameter"));
10813 return PVMFErrArgument;
10814 }
10815
10816 aNumParamElements = 1;
10817
10818 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerParameter() Out"));
10819 return PVMFSuccess;
10820 }
10821
10822
DoGetPlayerProductInfoParameter(PvmiKvp * & aParameters,int & aNumParamElements,int32 aIndex,PvmiKvpAttr reqattr)10823 PVMFStatus PVPlayerEngine::DoGetPlayerProductInfoParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
10824 {
10825 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() In"));
10826
10827 aNumParamElements = 0;
10828
10829 // Allocate memory for the KVP
10830 aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
10831 if (aParameters == NULL)
10832 {
10833 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for KVP failed"));
10834 return PVMFErrNoMemory;
10835 }
10836 oscl_memset(aParameters, 0, sizeof(PvmiKvp));
10837 // Allocate memory for the key string in KVP
10838 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVPLAYERCONFIG_KEYSTRING_SIZE * sizeof(char));
10839 if (memblock == NULL)
10840 {
10841 oscl_free(aParameters);
10842 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for key string"));
10843 return PVMFErrNoMemory;
10844 }
10845 oscl_strset(memblock, 0, PVPLAYERCONFIG_KEYSTRING_SIZE*sizeof(char));
10846 // Assign the key string buffer to KVP
10847 aParameters[0].key = memblock;
10848
10849 // Copy the key string
10850 oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/player/productinfo/"), 26);
10851 oscl_strncat(aParameters[0].key, PVPlayerConfigProdInfoKeys[aIndex].iString, oscl_strlen(PVPlayerConfigProdInfoKeys[aIndex].iString));
10852 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype=char*"), 25);
10853 aParameters[0].key[PVPLAYERCONFIG_KEYSTRING_SIZE-1] = 0;
10854
10855 // Copy the requested info
10856 switch (aIndex)
10857 {
10858 case PRODUCTNAME: // "productname"
10859 if (reqattr == PVMI_KVPATTR_CUR)
10860 {
10861 // Return current value
10862 // Allocate memory for the string
10863 char* curstr = (char*)oscl_malloc(iProdInfoProdName.get_size() + 1);
10864 if (curstr == NULL)
10865 {
10866 oscl_free(aParameters[0].key);
10867 oscl_free(aParameters);
10868 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
10869 return PVMFErrNoMemory;
10870 }
10871 oscl_strset(curstr, 0, iProdInfoProdName.get_size() + 1);
10872 // Copy and set
10873 oscl_strncpy(curstr, iProdInfoProdName.get_cstr(), iProdInfoProdName.get_size());
10874 aParameters[0].value.pChar_value = curstr;
10875 aParameters[0].length = iProdInfoProdName.get_size();
10876 aParameters[0].capacity = iProdInfoProdName.get_size() + 1;
10877 }
10878 else if (reqattr == PVMI_KVPATTR_DEF)
10879 {
10880 // Return default
10881 // Allocate memory for the string
10882 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_PRODNAME_STRING);
10883 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
10884 if (defstr == NULL)
10885 {
10886 oscl_free(aParameters[0].key);
10887 oscl_free(aParameters);
10888 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
10889 return PVMFErrNoMemory;
10890 }
10891 // Copy and set
10892 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PRODNAME_STRING), defstrlen);
10893 defstr[defstrlen] = 0;
10894 aParameters[0].value.pChar_value = defstr;
10895 aParameters[0].capacity = defstrlen + 1;
10896 aParameters[0].length = defstrlen;
10897 }
10898 else
10899 {
10900 // Return capability
10901 // Empty string
10902 aParameters[0].value.pChar_value = NULL;
10903 aParameters[0].capacity = 0;
10904 aParameters[0].length = 0;
10905 }
10906 break;
10907
10908 case PARTNUMBER: // "partnumber"
10909 if (reqattr == PVMI_KVPATTR_CUR)
10910 {
10911 // Return current value
10912 // Allocate memory for the string
10913 char* curstr = (char*)oscl_malloc(iProdInfoPartNum.get_size() + 1);
10914 if (curstr == NULL)
10915 {
10916 oscl_free(aParameters[0].key);
10917 oscl_free(aParameters);
10918 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
10919 return PVMFErrNoMemory;
10920 }
10921 oscl_strset(curstr, 0, iProdInfoPartNum.get_size() + 1);
10922 // Copy and set
10923 oscl_strncpy(curstr, iProdInfoPartNum.get_cstr(), iProdInfoPartNum.get_size());
10924 aParameters[0].value.pChar_value = curstr;
10925 aParameters[0].length = iProdInfoPartNum.get_size();
10926 aParameters[0].capacity = iProdInfoPartNum.get_size() + 1;
10927 }
10928 else if (reqattr == PVMI_KVPATTR_DEF)
10929 {
10930 // Return default
10931 // Allocate memory for the string
10932 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_PARTNUM_STRING);
10933 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
10934 if (defstr == NULL)
10935 {
10936 oscl_free(aParameters[0].key);
10937 oscl_free(aParameters);
10938 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
10939 return PVMFErrNoMemory;
10940 }
10941 // Copy and set
10942 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_PARTNUM_STRING), defstrlen);
10943 defstr[defstrlen] = 0;
10944 aParameters[0].value.pChar_value = defstr;
10945 aParameters[0].capacity = defstrlen + 1;
10946 aParameters[0].length = defstrlen;
10947 }
10948 else
10949 {
10950 // Return capability
10951 // Empty string
10952 aParameters[0].value.pChar_value = NULL;
10953 aParameters[0].capacity = 0;
10954 aParameters[0].length = 0;
10955 }
10956 break;
10957
10958 case HARDWAREPLATFORM: // "hardwareplatform"
10959 if (reqattr == PVMI_KVPATTR_CUR)
10960 {
10961 // Return current value
10962 // Allocate memory for the string
10963 char* curstr = (char*)oscl_malloc(iProdInfoHWPlatform.get_size() + 1);
10964 if (curstr == NULL)
10965 {
10966 oscl_free(aParameters[0].key);
10967 oscl_free(aParameters);
10968 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
10969 return PVMFErrNoMemory;
10970 }
10971 oscl_strset(curstr, 0, iProdInfoHWPlatform.get_size() + 1);
10972 // Copy and set
10973 oscl_strncpy(curstr, iProdInfoHWPlatform.get_cstr(), iProdInfoHWPlatform.get_size());
10974 aParameters[0].value.pChar_value = curstr;
10975 aParameters[0].length = iProdInfoHWPlatform.get_size();
10976 aParameters[0].capacity = iProdInfoHWPlatform.get_size() + 1;
10977 }
10978 else if (reqattr == PVMI_KVPATTR_DEF)
10979 {
10980 // Return default
10981 // Allocate memory for the string
10982 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_HWPLATFORM_STRING);
10983 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
10984 if (defstr == NULL)
10985 {
10986 oscl_free(aParameters[0].key);
10987 oscl_free(aParameters);
10988 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
10989 return PVMFErrNoMemory;
10990 }
10991 // Copy and set
10992 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_HWPLATFORM_STRING), defstrlen);
10993 defstr[defstrlen] = 0;
10994 aParameters[0].value.pChar_value = defstr;
10995 aParameters[0].capacity = defstrlen + 1;
10996 aParameters[0].length = defstrlen;
10997 }
10998 else
10999 {
11000 // Return capability
11001 // Empty string
11002 aParameters[0].value.pChar_value = NULL;
11003 aParameters[0].capacity = 0;
11004 aParameters[0].length = 0;
11005 }
11006 break;
11007
11008 case SOFTWAREPLATFORM: // "softwareplatform"
11009 if (reqattr == PVMI_KVPATTR_CUR)
11010 {
11011 // Return current value
11012 // Allocate memory for the string
11013 char* curstr = (char*)oscl_malloc(iProdInfoSWPlatform.get_size() + 1);
11014 if (curstr == NULL)
11015 {
11016 oscl_free(aParameters[0].key);
11017 oscl_free(aParameters);
11018 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
11019 return PVMFErrNoMemory;
11020 }
11021 oscl_strset(curstr, 0, iProdInfoSWPlatform.get_size() + 1);
11022 // Copy and set
11023 oscl_strncpy(curstr, iProdInfoSWPlatform.get_cstr(), iProdInfoSWPlatform.get_size());
11024 aParameters[0].value.pChar_value = curstr;
11025 aParameters[0].length = iProdInfoSWPlatform.get_size();
11026 aParameters[0].capacity = iProdInfoSWPlatform.get_size() + 1;
11027 }
11028 else if (reqattr == PVMI_KVPATTR_DEF)
11029 {
11030 // Return default
11031 // Allocate memory for the string
11032 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_SWPLATFORM_STRING);
11033 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
11034 if (defstr == NULL)
11035 {
11036 oscl_free(aParameters[0].key);
11037 oscl_free(aParameters);
11038 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
11039 return PVMFErrNoMemory;
11040 }
11041 // Copy and set
11042 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_SWPLATFORM_STRING), defstrlen);
11043 defstr[defstrlen] = 0;
11044 aParameters[0].value.pChar_value = defstr;
11045 aParameters[0].capacity = defstrlen + 1;
11046 aParameters[0].length = defstrlen;
11047 }
11048 else
11049 {
11050 // Return capability
11051 // Empty string
11052 aParameters[0].value.pChar_value = NULL;
11053 aParameters[0].capacity = 0;
11054 aParameters[0].length = 0;
11055 }
11056 break;
11057
11058 case DEVICE: // "device"
11059 if (reqattr == PVMI_KVPATTR_CUR)
11060 {
11061 // Return current value
11062 // Allocate memory for the string
11063 char* curstr = (char*)oscl_malloc(iProdInfoDevice.get_size() + 1);
11064 if (curstr == NULL)
11065 {
11066 oscl_free(aParameters[0].key);
11067 oscl_free(aParameters);
11068 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
11069 return PVMFErrNoMemory;
11070 }
11071 oscl_strset(curstr, 0, iProdInfoDevice.get_size() + 1);
11072 // Copy and set
11073 oscl_strncpy(curstr, iProdInfoPartNum.get_cstr(), iProdInfoDevice.get_size());
11074 aParameters[0].value.pChar_value = curstr;
11075 aParameters[0].length = iProdInfoDevice.get_size();
11076 aParameters[0].capacity = iProdInfoDevice.get_size() + 1;
11077 }
11078 else if (reqattr == PVMI_KVPATTR_DEF)
11079 {
11080 // Return default
11081 // Allocate memory for the string
11082 int32 defstrlen = oscl_strlen(PVPLAYERENGINE_PRODINFO_DEVICE_STRING);
11083 char* defstr = (char*)oscl_malloc((defstrlen + 1) * sizeof(char));
11084 if (defstr == NULL)
11085 {
11086 oscl_free(aParameters[0].key);
11087 oscl_free(aParameters);
11088 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Memory allocation for char* string failed"));
11089 return PVMFErrNoMemory;
11090 }
11091 // Copy and set
11092 oscl_strncpy(defstr, _STRLIT_CHAR(PVPLAYERENGINE_PRODINFO_DEVICE_STRING), defstrlen);
11093 defstr[defstrlen] = 0;
11094 aParameters[0].value.pChar_value = defstr;
11095 aParameters[0].capacity = defstrlen + 1;
11096 aParameters[0].length = defstrlen;
11097 }
11098 else
11099 {
11100 // Return capability
11101 // Empty string
11102 aParameters[0].value.pChar_value = NULL;
11103 aParameters[0].capacity = 0;
11104 aParameters[0].length = 0;
11105 }
11106 break;
11107
11108 default:
11109 // Invalid index
11110 oscl_free(aParameters[0].key);
11111 oscl_free(aParameters);
11112 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Invalid index for product info"));
11113 return PVMFErrArgument;
11114 }
11115
11116 aNumParamElements = 1;
11117
11118 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerProductInfoParameter() Out"));
11119 return PVMFSuccess;
11120 }
11121
11122
DoVerifyAndSetPlayerParameter(PvmiKvp & aParameter,bool aSetParam)11123 PVMFStatus PVPlayerEngine::DoVerifyAndSetPlayerParameter(PvmiKvp& aParameter, bool aSetParam)
11124 {
11125 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() In"));
11126
11127 // Determine the valtype
11128 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
11129 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
11130 {
11131 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Valtype in key string unknown"));
11132 return PVMFErrArgument;
11133 }
11134 // Retrieve the third component from the key string
11135 char* compstr = NULL;
11136 pv_mime_string_extract_type(2, aParameter.key, compstr);
11137
11138 int32 engcomp3ind = 0;
11139 for (engcomp3ind = 0; engcomp3ind < PVPLAYERCONFIG_BASE_NUMKEYS; ++engcomp3ind)
11140 {
11141 // Go through each engine component string at 3rd level
11142 if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigBaseKeys[engcomp3ind].iString)) >= 0)
11143 {
11144 // Break out of the for loop
11145 break;
11146 }
11147 }
11148
11149 if (engcomp3ind >= PVPLAYERCONFIG_BASE_NUMKEYS || engcomp3ind == PRODUCTINFO)
11150 {
11151 // Match couldn't be found or non-leaf node ("productinfo") specified
11152 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Unsupported key or non-leaf node"));
11153 return PVMFErrArgument;
11154 }
11155
11156 // Verify the valtype
11157 if (keyvaltype != PVPlayerConfigBaseKeys[engcomp3ind].iValueType)
11158 {
11159 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Valtype does not match for key"));
11160 return PVMFErrArgument;
11161 }
11162
11163 switch (engcomp3ind)
11164 {
11165 case PBPOS_UNITS: // "pbpos_units"
11166 {
11167 // Validate
11168 if (aParameter.value.pChar_value == NULL)
11169 {
11170 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() char* string for pbpos_units is NULL"));
11171 return PVMFErrArgument;
11172 }
11173
11174 // Check the specified unit
11175 // Use sample number as the invalid default since it is not allowed
11176 PVPPlaybackPositionUnit newposunit = PVPPBPOSUNIT_UNKNOWN;
11177 if (oscl_strncmp(aParameter.value.pChar_value, _STRLIT_CHAR("PVPPBPOSUNIT_SEC"), 16) == 0)
11178 {
11179 newposunit = PVPPBPOSUNIT_SEC;
11180 }
11181 else if (oscl_strncmp(aParameter.value.pChar_value, _STRLIT_CHAR("PVPPBPOSUNIT_MIN"), 16) == 0)
11182 {
11183 newposunit = PVPPBPOSUNIT_MIN;
11184 }
11185 else if (oscl_strncmp(aParameter.value.pChar_value, _STRLIT_CHAR("PVPPBPOSUNIT_MILLISEC"), 21) == 0)
11186 {
11187 newposunit = PVPPBPOSUNIT_MILLISEC;
11188 }
11189
11190 if (newposunit == PVPPBPOSUNIT_UNKNOWN)
11191 {
11192 // Couldn't determine the new units
11193 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid units for pbpos_units"));
11194 return PVMFErrArgument;
11195 }
11196 // Change the config if to set
11197 if (aSetParam)
11198 {
11199 iPBPosStatusUnit = newposunit;
11200 }
11201 }
11202 break;
11203
11204 case PBPOS_INTERVAL: // "pbpos_interval"
11205 // Check if within range
11206 if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MIN ||
11207 aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_PBPOSSTATUSINTERVAL_MAX)
11208 {
11209 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for pbpos_interval"));
11210 return PVMFErrArgument;
11211 }
11212 // Change the config if to set
11213 if (aSetParam)
11214 {
11215 iPBPosStatusInterval = aParameter.value.uint32_value;
11216 }
11217 break;
11218
11219 case ENDTIMECHECK_INTERVAL: // "endtimecheck_interval"
11220 // Check if within range
11221 if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MIN ||
11222 aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_ENDTIMECHECKINTERVAL_MAX)
11223 {
11224 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for endtimecheck_interval"));
11225 return PVMFErrArgument;
11226 }
11227 // Change the config if to set
11228 if (aSetParam)
11229 {
11230 iEndTimeCheckInterval = aParameter.value.uint32_value;
11231 }
11232 break;
11233
11234 case SEEKTOSYNCPOINT: // "seektosyncpoint"
11235 // Nothing to validate since it is boolean
11236 // Change the config if to set
11237 if (aSetParam)
11238 {
11239 iSeekToSyncPoint = aParameter.value.bool_value;
11240 }
11241 break;
11242
11243 case SKIPTOREQUESTEDPOSITION: // "skiptorequestedpos"
11244 // Nothing to validate since it is boolean
11245 // Change the config if to set
11246 if (aSetParam)
11247 {
11248 iSkipToRequestedPosition = aParameter.value.bool_value;
11249 }
11250 break;
11251
11252 case SYNCPOINTSEEKWINDOW: // "syncpointseekwindow"
11253 // Check if within range
11254 if (aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_SEEKTOSYNCPOINTWINDOW_MAX)
11255 {
11256 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for syncpointseekwindow"));
11257 return PVMFErrArgument;
11258 }
11259 // Change the config if to set
11260 if (aSetParam)
11261 {
11262 iSyncPointSeekWindow = aParameter.value.uint32_value;
11263 }
11264 break;
11265
11266 case SYNCMARGIN_VIDEO: // "syncmargin_video"
11267 case SYNCMARGIN_AUDIO: // "syncmargin_audio"
11268 case SYNCMARGIN_TEXT: // "syncmargin_text"
11269 {
11270 range_int32* ri32 = (range_int32*)aParameter.value.key_specific_value;
11271 if (ri32 == NULL)
11272 {
11273 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() ksv for syncmargin is NULL"));
11274 return PVMFErrArgument;
11275 }
11276
11277 // Check if within range
11278 if (ri32->min < PVPLAYERENGINE_CONFIG_SYNCMARGIN_MIN ||
11279 ri32->min > PVPLAYERENGINE_CONFIG_SYNCMARGIN_MAX ||
11280 ri32->max < PVPLAYERENGINE_CONFIG_SYNCMARGIN_MIN ||
11281 ri32->max > PVPLAYERENGINE_CONFIG_SYNCMARGIN_MAX)
11282 {
11283 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid range for syncmargin"));
11284 return PVMFErrArgument;
11285 }
11286
11287 // Change the config if to set
11288 if (aSetParam)
11289 {
11290 return DoSetConfigSyncMargin(ri32->min, ri32->max, engcomp3ind - 7);
11291 }
11292 }
11293 break;
11294
11295 case NODECMD_TIMEOUT: // "nodecmd_timeout"
11296 // Check if within range
11297 if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MIN ||
11298 aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_NODECMDTIMEOUT_MAX)
11299 {
11300 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for ndoecmd_timeout"));
11301 return PVMFErrArgument;
11302 }
11303 // Change the config if to set
11304 if (aSetParam)
11305 {
11306 iNodeCmdTimeout = aParameter.value.uint32_value;
11307 }
11308 break;
11309
11310 case NODEDATAQUEIUING_TIMEOUT: // "nodedataqueuing_timeout"
11311 // Check if within range
11312 if (aParameter.value.uint32_value < PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MIN ||
11313 aParameter.value.uint32_value > PVPLAYERENGINE_CONFIG_NODEDATAQUEUINGTIMEOUT_MAX)
11314 {
11315 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid value for nodedataqueuing_timeout"));
11316 return PVMFErrArgument;
11317 }
11318 // Change the config if to set
11319 if (aSetParam)
11320 {
11321 iNodeDataQueuingTimeout = aParameter.value.uint32_value;
11322 }
11323 break;
11324
11325 case PBPOS_ENABLE: // "pbpos_enable"
11326 // Nothing to validate since it is boolean
11327 // Change the config if to set
11328 if (aSetParam)
11329 {
11330 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() pbpos_enable set to %d", iPBPosEnable));
11331 bool prevPBPosEnable = iPBPosEnable;
11332 iPBPosEnable = aParameter.value.bool_value;
11333 if (prevPBPosEnable && !(aParameter.value.bool_value))
11334 {
11335 // Stop playback position reporting
11336 StopPlaybackStatusTimer();
11337 }
11338 else if (!prevPBPosEnable && (aParameter.value.bool_value))
11339 {
11340 // Start playback position reporting only when playback clock is running
11341 if (iPlaybackClock.GetState() == PVMFMediaClock::RUNNING)
11342 {
11343 StartPlaybackStatusTimer();
11344 }
11345 }
11346
11347 }
11348 break;
11349
11350 default:
11351 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Invalid index for player parameter"));
11352 return PVMFErrArgument;
11353 }
11354
11355 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerParameter() Out"));
11356 return PVMFSuccess;
11357 }
11358
11359
DoVerifyAndSetPlayerProductInfoParameter(PvmiKvp & aParameter,bool aSetParam)11360 PVMFStatus PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter(PvmiKvp& aParameter, bool aSetParam)
11361 {
11362 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() In"));
11363
11364 // Determine the valtype
11365 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
11366 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
11367 {
11368 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Valtype unknown"));
11369 return PVMFErrArgument;
11370 }
11371 // Retrieve the 4th component from the key string
11372 char* compstr = NULL;
11373 pv_mime_string_extract_type(3, aParameter.key, compstr);
11374
11375 int32 engcomp4ind = 0;
11376 for (engcomp4ind = 0; engcomp4ind < PVPLAYERCONFIG_PRODINFO_NUMKEYS; ++engcomp4ind)
11377 {
11378 // Go through each engine component string at 4th level
11379 if (pv_mime_strcmp(compstr, (char*)(PVPlayerConfigProdInfoKeys[engcomp4ind].iString)) >= 0)
11380 {
11381 // Break out of the for loop
11382 break;
11383 }
11384 }
11385
11386 if (engcomp4ind >= PVPLAYERCONFIG_PRODINFO_NUMKEYS)
11387 {
11388 // Match couldn't be found
11389 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Unsupported key"));
11390 return PVMFErrArgument;
11391 }
11392
11393 // Verify the valtype
11394 if (keyvaltype != PVPlayerConfigProdInfoKeys[engcomp4ind].iValueType)
11395 {
11396 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Valtype does not match for key"));
11397 return PVMFErrArgument;
11398 }
11399
11400 switch (engcomp4ind)
11401 {
11402 case PRODUCTNAME: // "productname"
11403 // Check if within range
11404 if (aParameter.value.pChar_value == NULL)
11405 {
11406 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
11407 return PVMFErrArgument;
11408 }
11409 // Change the config if to set
11410 if (aSetParam)
11411 {
11412 iProdInfoProdName = aParameter.value.pChar_value;
11413 }
11414 break;
11415
11416 case PARTNUMBER: // "partnumber"
11417 // Check if within range
11418 if (aParameter.value.pChar_value == NULL)
11419 {
11420 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
11421 return PVMFErrArgument;
11422 }
11423 // Change the config if to set
11424 if (aSetParam)
11425 {
11426 iProdInfoPartNum = aParameter.value.pChar_value;
11427 }
11428 break;
11429
11430 case HARDWAREPLATFORM: // "hardwareplatform"
11431 // Check if within range
11432 if (aParameter.value.pChar_value == NULL)
11433 {
11434 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
11435 return PVMFErrArgument;
11436 }
11437 // Change the config if to set
11438 if (aSetParam)
11439 {
11440 iProdInfoHWPlatform = aParameter.value.pChar_value;
11441 }
11442 break;
11443
11444 case SOFTWAREPLATFORM: // "softwareplatform"
11445 // Check if within range
11446 if (aParameter.value.pChar_value == NULL)
11447 {
11448 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
11449 return PVMFErrArgument;
11450 }
11451 // Change the config if to set
11452 if (aSetParam)
11453 {
11454 iProdInfoSWPlatform = aParameter.value.pChar_value;
11455 }
11456 break;
11457
11458 case DEVICE: // "device"
11459 // Check if within range
11460 if (aParameter.value.pChar_value == NULL)
11461 {
11462 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() char* string for productname is NULL"));
11463 return PVMFErrArgument;
11464 }
11465 // Change the config if to set
11466 if (aSetParam)
11467 {
11468 iProdInfoDevice = aParameter.value.pChar_value;
11469 }
11470 break;
11471
11472 default:
11473 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Invalid index for product info"));
11474 return PVMFErrArgument;
11475 }
11476
11477 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoVerifyAndSetPlayerProductInfoParameter() Out"));
11478 return PVMFSuccess;
11479 }
11480
11481
DoSetConfigSyncMargin(int32 aEarlyMargin,int32 aLateMargin,int32 aMediaType)11482 PVMFStatus PVPlayerEngine::DoSetConfigSyncMargin(int32 aEarlyMargin, int32 aLateMargin, int32 aMediaType)
11483 {
11484 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetConfigSyncMargin() In"));
11485
11486 if (aMediaType == 0)
11487 {
11488 // Video
11489 iSyncMarginVideo.min = aEarlyMargin;
11490 iSyncMarginVideo.max = aLateMargin;
11491
11492 // Find the video datapath in the list
11493 int32 vdpind = -1;
11494 if (FindDatapathForTrackUsingMimeString(true, false, false, vdpind) == true)
11495 {
11496 PVPlayerEngineDatapath* pvpedp = &(iDatapathList[vdpind]);
11497 if (pvpedp->iDatapath)
11498 {
11499 if (pvpedp->iSinkNodeSyncCtrlIF)
11500 {
11501 pvpedp->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginVideo.min), iSyncMarginVideo.max);
11502 }
11503 }
11504 }
11505 }
11506 else if (aMediaType == 1)
11507 {
11508 // Audio
11509 iSyncMarginAudio.min = aEarlyMargin;
11510 iSyncMarginAudio.max = aLateMargin;
11511
11512 // Find the audio datapath in the list
11513 int32 adpind = -1;
11514 if (FindDatapathForTrackUsingMimeString(false, true, false, adpind) == true)
11515 {
11516 PVPlayerEngineDatapath* pvpedp = &(iDatapathList[adpind]);
11517 if (pvpedp->iDatapath)
11518 {
11519 if (pvpedp->iSinkNodeSyncCtrlIF)
11520 {
11521 pvpedp->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginAudio.min), iSyncMarginAudio.max);
11522 }
11523 }
11524 }
11525 }
11526 else if (aMediaType == 2)
11527 {
11528 // Text
11529 iSyncMarginText.min = aEarlyMargin;
11530 iSyncMarginText.max = aLateMargin;
11531
11532 // Find the text datapath in the list
11533 int32 tdpind = -1;
11534 if (FindDatapathForTrackUsingMimeString(false, false, true, tdpind) == true)
11535 {
11536 PVPlayerEngineDatapath* pvpedp = &(iDatapathList[tdpind]);
11537 if (pvpedp->iDatapath)
11538 {
11539 if (pvpedp->iSinkNodeSyncCtrlIF)
11540 {
11541 pvpedp->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginText.min), iSyncMarginText.max);
11542 }
11543 }
11544 }
11545 }
11546 else
11547 {
11548 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoSetConfigSyncMargin() Invalid media type index"));
11549 return PVMFErrArgument;
11550 }
11551
11552 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSetConfigSyncMargin() Out"));
11553 return PVMFSuccess;
11554 }
11555
11556
AllocateEngineContext(PVPlayerEngineDatapath * aEngineDatapath,PVMFNodeInterface * aNode,PVPlayerDatapath * aDatapath,PVCommandId aCmdId,OsclAny * aCmdContext,int32 aCmdType)11557 PVPlayerEngineContext* PVPlayerEngine::AllocateEngineContext(PVPlayerEngineDatapath* aEngineDatapath, PVMFNodeInterface* aNode, PVPlayerDatapath* aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext, int32 aCmdType)
11558 {
11559 // Allocate memory for the context from the fixed size memory pool
11560 PVPlayerEngineContext* context = NULL;
11561 int32 leavecode = 0;
11562 OSCL_TRY(leavecode, context = (PVPlayerEngineContext*)(iCurrentContextListMemPool.allocate(sizeof(PVPlayerEngineContext))));
11563 OSCL_FIRST_CATCH_ANY(leavecode,
11564 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::AllocateEngineContext() allocate on iCurrentContextListMemPool did a leave!"));
11565 OSCL_ASSERT(false));
11566
11567 OSCL_ASSERT(context);
11568
11569 // Set the context info
11570 context->iEngineDatapath = aEngineDatapath;
11571 context->iNode = aNode;
11572 context->iDatapath = aDatapath;
11573 context->iCmdId = aCmdId;
11574 context->iCmdContext = aCmdContext;
11575 context->iCmdType = aCmdType;
11576
11577 // Save the context in the list
11578 leavecode = 0;
11579 OSCL_TRY(leavecode, iCurrentContextList.push_back(context));
11580 OSCL_FIRST_CATCH_ANY(leavecode,
11581 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::AllocateEngineContext() Push back on the context list did a leave!"));
11582 iCurrentContextListMemPool.deallocate((OsclAny*)context);
11583 OSCL_ASSERT(false);
11584 return NULL;);
11585
11586 return context;
11587 }
11588
11589
FreeEngineContext(PVPlayerEngineContext * aContext)11590 void PVPlayerEngine::FreeEngineContext(PVPlayerEngineContext* aContext)
11591 {
11592 OSCL_ASSERT(aContext);
11593
11594 // Remove the context from the list
11595 uint32 i = 0;
11596 bool foundcontext = false;
11597 for (i = 0; i < iCurrentContextList.size(); ++i)
11598 {
11599 if (iCurrentContextList[i] == aContext)
11600 {
11601 foundcontext = true;
11602 break;
11603 }
11604 }
11605
11606 if (foundcontext)
11607 {
11608 iCurrentContextList.erase(iCurrentContextList.begin() + i);
11609 // Free the memory used by context in the memory pool
11610 iCurrentContextListMemPool.deallocate((OsclAny*)aContext);
11611 }
11612 else
11613 {
11614 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::FreeEngineContext() Context not on current list (0x%x). CmdType %d", aContext, aContext->iCmdType));
11615 OSCL_ASSERT(false);
11616 // Don't return to memory pool since it could add multiple entries
11617 // of same address in free list
11618 }
11619 }
11620
11621
HandleSourceNodeQueryInitIF(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)11622 void PVPlayerEngine::HandleSourceNodeQueryInitIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
11623 {
11624 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
11625 (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() Tick=%d", OsclTickCount::TickCount()));
11626
11627 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() In"));
11628
11629 PVMFStatus cmdstatus;
11630 bool rescheduleAO = false;
11631
11632 switch (aNodeResp.GetCmdStatus())
11633 {
11634 case PVMFSuccess:
11635 if (iSourceNodePVInterfaceInit)
11636 {
11637 iSourceNodeInitIF = (PVMFDataSourceInitializationExtensionInterface*)iSourceNodePVInterfaceInit;
11638 iSourceNodePVInterfaceInit = NULL;
11639 }
11640 // Query for track selection interface
11641 cmdstatus = DoSourceNodeQueryTrackSelIF(aNodeContext.iCmdId, aNodeContext.iCmdContext);
11642 if (cmdstatus != PVMFSuccess)
11643 {
11644 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
11645 {
11646 iRollOverState = RollOverStateStart;
11647 rescheduleAO = true;
11648 }
11649 else
11650 {
11651 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
11652 (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() DoSourceNodeQueryTrackSelIF failed, Add EH command"));
11653 iCommandCompleteStatusInErrorHandling = cmdstatus;
11654 iCommandCompleteErrMsgInErrorHandling = NULL;
11655 if (iRollOverState == RollOverStateInProgress)
11656 {
11657 // Init is the current ongoing cmd so queue Init EH cmd
11658 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
11659 }
11660 else
11661 {
11662 // AddDataSource cmd is Current Command, queue ADS EH cmd
11663 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
11664 }
11665 iRollOverState = RollOverStateIdle;
11666 }
11667 }
11668 break;
11669
11670 default:
11671 {
11672 iSourceNodePVInterfaceInit = NULL;
11673 iSourceNodeInitIF = NULL;
11674
11675 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
11676 {
11677 iRollOverState = RollOverStateStart;
11678 rescheduleAO = true;
11679 }
11680 else
11681 {
11682 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
11683 (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() failed, Add EH command"));
11684 cmdstatus = aNodeResp.GetCmdStatus();
11685 PVMFErrorInfoMessageInterface* nextmsg = NULL;
11686 if (aNodeResp.GetEventExtensionInterface())
11687 {
11688 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
11689 }
11690
11691 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
11692 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
11693 iCommandCompleteStatusInErrorHandling = cmdstatus;
11694 if (iRollOverState == RollOverStateInProgress)
11695 {
11696 // Init is the current ongoing cmd so queue Init EH cmd
11697 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
11698 }
11699 else
11700 {
11701 // AddDataSource cmd is Current Command, queue ADS EH cmd
11702 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
11703 }
11704 iRollOverState = RollOverStateIdle;
11705 }
11706 }
11707 break;
11708 }
11709 if (rescheduleAO)
11710 {
11711 if (IsBusy())
11712 {
11713 Cancel();
11714 }
11715
11716 RunIfNotReady();
11717 }
11718
11719 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInitIF() Out"));
11720 }
11721
11722
HandleSourceNodeQueryTrackSelIF(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)11723 void PVPlayerEngine::HandleSourceNodeQueryTrackSelIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
11724 {
11725 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
11726 (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() Tick=%d", OsclTickCount::TickCount()));
11727
11728 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() In"));
11729
11730 PVMFStatus cmdstatus;
11731 bool rescheduleAO = false;
11732
11733 switch (aNodeResp.GetCmdStatus())
11734 {
11735 case PVMFSuccess:
11736 if (iSourceNodePVInterfaceTrackSel)
11737 {
11738 iSourceNodeTrackSelIF = (PVMFTrackSelectionExtensionInterface*)iSourceNodePVInterfaceTrackSel;
11739 iSourceNodePVInterfaceTrackSel = NULL;
11740 }
11741 // Query the source node for optional extension IFs
11742 cmdstatus = DoSourceNodeQueryInterfaceOptional(aNodeContext.iCmdId, aNodeContext.iCmdContext);
11743 if (cmdstatus != PVMFSuccess)
11744 {
11745 // If optional extension IFs are not available, just complete the AddDataSource command as success
11746 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
11747 {
11748 iRollOverState = RollOverStateStart;
11749 rescheduleAO = true;
11750 }
11751 else
11752 {
11753 iRollOverState = RollOverStateIdle;
11754 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
11755 }
11756 }
11757 break;
11758
11759 default:
11760 {
11761 iSourceNodePVInterfaceTrackSel = NULL;
11762 iSourceNodeTrackSelIF = NULL;
11763
11764 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
11765 {
11766 iRollOverState = RollOverStateStart;
11767 rescheduleAO = true;
11768 }
11769 else
11770 {
11771 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
11772 (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() failed, Add EH Command"));
11773 cmdstatus = aNodeResp.GetCmdStatus();
11774 PVMFErrorInfoMessageInterface* nextmsg = NULL;
11775 if (aNodeResp.GetEventExtensionInterface())
11776 {
11777 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
11778 }
11779
11780 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
11781 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
11782
11783 iCommandCompleteStatusInErrorHandling = cmdstatus;
11784 if (iRollOverState == RollOverStateInProgress)
11785 {
11786 // Init is the current ongoing cmd so queue Init EH cmd
11787 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
11788 }
11789 else
11790 {
11791 // AddDataSource cmd is Current Command, queue ADS EH cmd
11792 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE, NULL, NULL, NULL, false);
11793 }
11794 iRollOverState = RollOverStateIdle;
11795 }
11796 }
11797 break;
11798 }
11799 if (rescheduleAO)
11800 {
11801 if (IsBusy())
11802 {
11803 Cancel();
11804 }
11805
11806 RunIfNotReady();
11807 }
11808 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryTrackSelIF() Out"));
11809 }
11810
11811
HandleSourceNodeQueryInterfaceOptional(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)11812 void PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
11813 {
11814 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
11815 (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
11816
11817 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() In"));
11818
11819 // Determine QueryInterface() for which interface completed
11820 if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryTrackLevelInfoIF)
11821 {
11822 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceTrackLevelInfo)
11823 {
11824 iSourceNodeTrackLevelInfoIF = (PVMFTrackLevelInfoExtensionInterface*)iSourceNodePVInterfaceTrackLevelInfo;
11825 iSourceNodePVInterfaceTrackLevelInfo = NULL;
11826 }
11827 else
11828 {
11829 // Track level info IF is not available in this data source
11830 iSourceNodePVInterfaceTrackLevelInfo = NULL;
11831 iSourceNodeTrackLevelInfoIF = NULL;
11832 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Track level info IF not available"));
11833 }
11834 }
11835 else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryPBCtrlIF)
11836 {
11837 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfacePBCtrl)
11838 {
11839 iSourceNodePBCtrlIF = (PvmfDataSourcePlaybackControlInterface*)iSourceNodePVInterfacePBCtrl;
11840 iSourceNodePVInterfacePBCtrl = NULL;
11841 }
11842 else
11843 {
11844 // Playback control is not available in this data source
11845 iSourceNodePVInterfacePBCtrl = NULL;
11846 iSourceNodePBCtrlIF = NULL;
11847 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Position control IF not available"));
11848 }
11849 }
11850 else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryDirCtrlIF)
11851 {
11852 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceDirCtrl)
11853 {
11854 iSourceNodeDirCtrlIF = (PvmfDataSourceDirectionControlInterface*)iSourceNodePVInterfaceDirCtrl;
11855 iSourceNodePVInterfaceDirCtrl = NULL;
11856 }
11857 else
11858 {
11859 // Direction control is not available in this data source
11860 iSourceNodePVInterfaceDirCtrl = NULL;
11861 iSourceNodeDirCtrlIF = NULL;
11862 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Direction control IF not available"));
11863 }
11864 }
11865 else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryMetadataIF)
11866 {
11867 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceMetadataExt)
11868 {
11869 iSourceNodeMetadataExtIF = (PVMFMetadataExtensionInterface*)iSourceNodePVInterfaceMetadataExt;
11870 iSourceNodePVInterfaceMetadataExt = NULL;
11871
11872 // Add the parser node's metadata extension IF to the list
11873 if (AddToMetadataInterfaceList(iSourceNodeMetadataExtIF, iSourceNodeSessionId, NULL, iSourceNode) != PVMFSuccess)
11874 {
11875 iSourceNodeMetadataExtIF->removeRef();
11876 iSourceNodeMetadataExtIF = NULL;
11877
11878 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Metadata IF could not be added to list"));
11879 }
11880 }
11881 else
11882 {
11883 // Metadata is not available in this data source
11884 iSourceNodePVInterfaceMetadataExt = NULL;
11885 iSourceNodeMetadataExtIF = NULL;
11886 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Metadata IF not available"));
11887 }
11888 }
11889 else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryCapConfigIF)
11890 {
11891 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceCapConfig)
11892 {
11893 iSourceNodeCapConfigIF = (PvmiCapabilityAndConfig*)iSourceNodePVInterfaceCapConfig;
11894 iSourceNodePVInterfaceCapConfig = NULL;
11895 }
11896 else
11897 {
11898 // Cap-config is not available in this data source
11899 iSourceNodePVInterfaceCapConfig = NULL;
11900 iSourceNodeCapConfigIF = NULL;
11901 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Cap-Config IF not available"));
11902 }
11903 }
11904 else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQueryCPMLicenseIF)
11905 {
11906 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceCPMLicense)
11907 {
11908 iSourceNodeCPMLicenseIF = (PVMFCPMPluginLicenseInterface*)iSourceNodePVInterfaceCPMLicense;
11909 iSourceNodePVInterfaceCPMLicense = NULL;
11910 }
11911 else
11912 {
11913 //CPM License is not available in this data source
11914 iSourceNodePVInterfaceCPMLicense = NULL;
11915 iSourceNodeCPMLicenseIF = NULL;
11916 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() CPM License IF not available"));
11917 }
11918 }
11919 else if (aNodeContext.iCmdType == PVP_CMD_SourceNodeQuerySrcNodeRegInitIF)
11920 {
11921 if ((aNodeResp.GetCmdStatus() == PVMFSuccess) && iSourceNodePVInterfaceRegInit)
11922 {
11923 iSourceNodeRegInitIF = (PVMFDataSourceNodeRegistryInitInterface*)iSourceNodePVInterfaceRegInit;
11924 iSourceNodePVInterfaceRegInit = NULL;
11925
11926 // Set source node regsitry
11927 iSourceNodeRegInitIF->SetPlayerNodeRegistry(&iPlayerNodeRegistry);
11928 }
11929 else
11930 {
11931 //Node Registry Init Extension Interface is not available in this data source
11932 iSourceNodePVInterfaceRegInit = NULL;
11933 iSourceNodeRegInitIF = NULL;
11934 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Src Node Registry Init IF not available"));
11935 }
11936 }
11937
11938 // Decrement the pending counter and complete the AddDataSource command if 0.
11939 --iNumPendingNodeCmd;
11940 if (iNumPendingNodeCmd == 0)
11941 {
11942 if (iRollOverState == RollOverStateInProgress)
11943 {
11944 SetRollOverKVPValues();
11945 PVMFStatus retval = DoSourceNodeInit(aNodeContext.iCmdId, aNodeContext.iCmdContext);
11946 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() - Source Roll Over In Progress - Doing Source Node Init"));
11947
11948 if (retval == PVMFSuccess)
11949 {
11950 SetEngineState(PVP_ENGINE_STATE_INITIALIZING);
11951 }
11952 else
11953 {
11954 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() - Source Roll Over In Progress - DoSourceNodeInit Failed"));
11955 if ((CheckForSourceRollOver() == true) && (iRollOverState == RollOverStateInProgress))
11956 {
11957 iRollOverState = RollOverStateStart;
11958 RunIfNotReady();
11959 }
11960 else
11961 {
11962 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
11963 (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() DoSourceNodeInit failed, Add EH Command"));
11964 iRollOverState = RollOverStateIdle;
11965 iCommandCompleteStatusInErrorHandling = retval;
11966 iCommandCompleteErrMsgInErrorHandling = NULL;
11967 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
11968 }
11969 }
11970 }
11971 else
11972 {
11973 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() All QueryInterface() commands complete so AddDataSource is complete"));
11974 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
11975 }
11976 }
11977 else
11978 {
11979 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() %d QueryInterface() commands are still pending", iNumPendingNodeCmd));
11980 }
11981
11982 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryInterfaceOptional() Out"));
11983 }
11984
HandleSourceNodeInit(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)11985 void PVPlayerEngine::HandleSourceNodeInit(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
11986 {
11987 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
11988 (0, "PVPlayerEngine::HandleSourceNodeInit() Tick=%d", OsclTickCount::TickCount()));
11989
11990 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInit() In"));
11991
11992 iRollOverState = RollOverStateIdle;
11993 PVMFStatus cmdstatus;
11994
11995 switch (aNodeResp.GetCmdStatus())
11996 {
11997 case PVMFSuccess:
11998 {
11999 // Try to retrieve the duration from the source node via metadata IF
12000 // Only if we din't got that value through PVMFInfoDurationAvailable informational event.
12001 if (!iSourceDurationAvailable)
12002 {
12003 if (DoSourceNodeGetDurationValue(aNodeContext.iCmdId, aNodeContext.iCmdContext) != PVMFSuccess)
12004 {
12005 // Duration could not be retrieved.
12006 // Not an error so complete so engine's Init()
12007 SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
12008 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
12009 }
12010 }
12011 else
12012 {
12013 // Duration is already available through Info event.
12014 // so complete engine's Init()
12015 SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
12016 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
12017 }
12018 }
12019 break;
12020
12021
12022 case PVMFErrLicenseRequired:
12023 case PVMFErrHTTPAuthenticationRequired:
12024 case PVMFErrRedirect:
12025 {
12026 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInit() PVMFErrLicenseRequired/PVMFErrHTTPAuthenticationRequired/PVMFErrRedirect"));
12027
12028 SetEngineState(PVP_ENGINE_STATE_IDLE);
12029 cmdstatus = aNodeResp.GetCmdStatus();
12030
12031 PVMFErrorInfoMessageInterface* nextmsg = NULL;
12032 if (aNodeResp.GetEventExtensionInterface())
12033 {
12034 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
12035 }
12036
12037 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
12038 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
12039
12040 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg), aNodeResp.GetEventData());
12041 errmsg->removeRef();
12042
12043 }
12044 break;
12045 case PVMFErrContentInvalidForProgressivePlayback:
12046 {
12047 SetEngineState(PVP_ENGINE_STATE_ERROR);
12048 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
12049
12050 cmdstatus = aNodeResp.GetCmdStatus();
12051
12052 PVMFErrorInfoMessageInterface* nextmsg = NULL;
12053 if (aNodeResp.GetEventExtensionInterface())
12054 {
12055 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
12056 }
12057
12058 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
12059 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
12060 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg), aNodeResp.GetEventData());
12061 errmsg->removeRef();
12062 }
12063 break;
12064
12065 default:
12066 {
12067 if (iState == PVP_ENGINE_STATE_INITIALIZING)
12068 {
12069 SetEngineState(PVP_ENGINE_STATE_IDLE);
12070 if (CheckForSourceRollOver() == false)
12071 {
12072 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() failed, Add EH Command"));
12073 cmdstatus = aNodeResp.GetCmdStatus();
12074
12075 PVMFErrorInfoMessageInterface* nextmsg = NULL;
12076 if (aNodeResp.GetEventExtensionInterface())
12077 {
12078 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
12079 }
12080
12081 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
12082 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
12083 iCommandCompleteStatusInErrorHandling = cmdstatus;
12084 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT, NULL, NULL, NULL, false);
12085 }
12086 else
12087 {
12088 // Initialization of source node failed so try alternates
12089 //reschedule to do source node roll over
12090 iRollOverState = RollOverStateStart;
12091 //remove any queued up auto-pause/auto-resume commands
12092 //they are no longer applicable since we are doing a change of sourcenode
12093 removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, true);
12094 removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, true);
12095 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() - Rescheduling to do source roll over"));
12096 RunIfNotReady();
12097 }
12098 }
12099 else
12100 {
12101 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() - Incorrect State - Asserting"));
12102 OSCL_ASSERT(false);
12103 }
12104 }
12105 break;
12106 }
12107
12108 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInit() Out"));
12109 }
12110
12111
HandleSourceNodeGetDurationValue(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12112 void PVPlayerEngine::HandleSourceNodeGetDurationValue(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12113 {
12114 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12115 (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Tick=%d", OsclTickCount::TickCount()));
12116
12117 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() In"));
12118
12119 switch (aNodeResp.GetCmdStatus())
12120 {
12121 case PVMFSuccess:
12122 {
12123 // Extract the duration and save it
12124 // Check that there is one KVP in value list
12125 if (iSourceDurationValueList.size() != 1)
12126 {
12127 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Value list size is not 1 (size=%d)",
12128 iSourceDurationValueList.size()));
12129 break;
12130 }
12131
12132 // Check that the key in KVP is not NULL
12133 if (iSourceDurationValueList[0].key == NULL)
12134 {
12135 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Value list key string is NULL"));
12136 break;
12137 }
12138
12139 // Check that value is for duration
12140 int retval = pv_mime_strstr(iSourceDurationValueList[0].key, (char*)_STRLIT_CHAR("duration"));
12141 if (retval == -1)
12142 {
12143 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Key string does not contain duration"));
12144 break;
12145 }
12146
12147 // Check that duration value is uint32. If not available assume uint32.
12148 PvmiKvpValueType durvaltype = GetValTypeFromKeyString(iSourceDurationValueList[0].key);
12149 if (durvaltype != PVMI_KVPVALTYPE_UINT32 && durvaltype != PVMI_KVPVALTYPE_UNKNOWN)
12150 {
12151 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Value type is not uint32 or unknown"));
12152 break;
12153 }
12154 iSourceDurationInMS = iSourceDurationValueList[0].value.uint32_value;
12155
12156 // Check the timescale. If not available, assume millisecond (1000)
12157 const char* retsubstr = NULL;
12158 uint32 retsubstrlen = 0;
12159 uint32 tsparamlen = oscl_strlen(_STRLIT_CHAR("timescale="));
12160 retsubstr = oscl_strstr(iSourceDurationValueList[0].key, _STRLIT_CHAR("timescale="));
12161 if (retsubstr != NULL)
12162 {
12163 retsubstrlen = oscl_strlen(retsubstr);
12164 if (retsubstrlen > tsparamlen)
12165 {
12166 uint32 timescale = 0;
12167 PV_atoi((char*)(retsubstr + tsparamlen), 'd', (retsubstrlen - tsparamlen), timescale);
12168 if (timescale > 0 && timescale != 1000)
12169 {
12170 // Convert to milliseconds
12171 MediaClockConverter mcc(timescale);
12172 mcc.update_clock(iSourceDurationInMS);
12173 iSourceDurationInMS = mcc.get_converted_ts(1000);
12174 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Timescale for duration is %d",
12175 timescale));
12176 }
12177 }
12178 }
12179
12180 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Duration in millisec is %d",
12181 iSourceDurationInMS));
12182 iSourceDurationAvailable = true;
12183 }
12184 break;
12185
12186 default:
12187 {
12188 // Duration is not available
12189 // Do nothing
12190 }
12191 break;
12192 }
12193
12194 // Release any metadata values back to source node
12195 // and then clear it
12196 if (iSourceDurationValueList.empty() == false)
12197 {
12198 if (iSourceNodeMetadataExtIF != NULL)
12199 {
12200 iSourceNodeMetadataExtIF->ReleaseNodeMetadataValues(iSourceDurationValueList, 0, iSourceDurationValueList.size());
12201 }
12202 iSourceDurationValueList.clear();
12203 }
12204
12205 // Engine's Init() is now complete
12206 SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
12207 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
12208
12209 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeGetDurationValue() Out"));
12210 }
12211
HandleSourceNodeSetDataSourceRate(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12212 void PVPlayerEngine::HandleSourceNodeSetDataSourceRate(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12213 {
12214 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceRate() In"));
12215
12216 PVMFStatus cmdstatus = aNodeResp.GetCmdStatus();
12217
12218 if (cmdstatus != PVMFSuccess)
12219 {
12220 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus);
12221 }
12222 else
12223 {
12224 //Continue on to sink rate change.
12225 cmdstatus = DoSinkNodeChangeClockRate();
12226 if (cmdstatus != PVMFSuccess)
12227 {
12228 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus);
12229 }
12230 else
12231 {
12232 //Rate Change is complete.
12233
12234 //Install the updated rate and timebase.
12235 UpdateTimebaseAndRate();
12236
12237 //Start direction change sequence if needed.
12238 if (iPlaybackDirection_New != iPlaybackDirection)
12239 {
12240 cmdstatus = UpdateCurrentDirection(aNodeContext.iCmdId, aNodeContext.iCmdContext);
12241 switch (cmdstatus)
12242 {
12243 case PVMFPending:
12244 //wait on node command completion and call to HandleSourceNodeSetDataSourceDirection
12245 break;
12246 case PVMFSuccess:
12247 //engine command is done, but direction is not actually set on the
12248 //source until the Resume or Prepare happens.
12249 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
12250 break;
12251 default:
12252 //failed!
12253 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus);
12254 break;
12255 }
12256 }
12257 else
12258 {
12259 //SetPlaybackRate is complete!
12260 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
12261 }
12262 }
12263 }
12264
12265 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceRate() Out"));
12266 }
12267
DoSinkNodeChangeClockRate()12268 PVMFStatus PVPlayerEngine::DoSinkNodeChangeClockRate()
12269 {
12270 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeChangeClockRate() In"));
12271
12272 // Check with sink nodes
12273 PVMFStatus cmdstatus = PVMFSuccess;
12274
12275 for (uint32 i = 0; i < iDatapathList.size(); ++i)
12276 {
12277 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
12278 {
12279 cmdstatus = iDatapathList[i].iSinkNodeSyncCtrlIF->ChangeClockRate(iPlaybackClockRate_New);
12280
12281 if (cmdstatus != PVMFSuccess)
12282 {
12283 // One of the sinks reported not supported so don't allow the clock rate change.
12284 break;
12285 }
12286 }
12287 }
12288
12289 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoSinkNodeChangeClockRate() Out"));
12290 return cmdstatus;
12291 }
12292
UpdateDirection(PVMFTimestamp aNPT,PVMFTimestamp aMediaTS,PVPPlaybackPosition & aPos)12293 void PVPlayerEngine::UpdateDirection(PVMFTimestamp aNPT, PVMFTimestamp aMediaTS, PVPPlaybackPosition& aPos)
12294 {
12295 //First note the current observed NPT value. We will reposition to this
12296 //value.
12297 PVPPlaybackPosition curpos;
12298 curpos.iIndeterminate = false;
12299 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
12300 GetPlaybackClockPosition(curpos);
12301 aPos = curpos;
12302
12303 //Install the new value for direction.
12304 iPlaybackDirection = iPlaybackDirection_New;
12305
12306 //Save the start NPT and TS
12307 iStartNPT = aNPT;
12308 iStartMediaDataTS = aMediaTS;
12309
12310 if (iPlaybackDirection_New < 0)
12311 {
12312 if (aPos.iPosValue.millisec_value >= iSourceDurationInMS)
12313 {
12314 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::UpdateDirection() Current pos %dms is more than Duration %dms", aPos.iPosValue.millisec_value, iSourceDurationInMS));
12315 if (ConvertFromMillisec((uint32)(iSourceDurationInMS - 1), aPos) != PVMFSuccess)
12316 {
12317 // Other position units are not supported yet
12318 aPos.iIndeterminate = true;
12319 }
12320 }
12321 }
12322
12323 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
12324 (0, "PVPlayerEngine::UpdateDirection() Direction %d New Start NPT %d Start Media Data TS %d, Repos NPT %d, Pos Indeterminate %d"
12325 , iPlaybackDirection
12326 , iStartNPT
12327 , iStartMediaDataTS
12328 , aPos.iPosValue.millisec_value
12329 , aPos.iIndeterminate));
12330 }
12331
UpdateTimebaseAndRate()12332 void PVPlayerEngine::UpdateTimebaseAndRate()
12333 {
12334 if (iPlaybackClockRate_New == iPlaybackClockRate
12335 && iOutsideTimebase_New == iOutsideTimebase)
12336 return;//no update needed
12337
12338 //Install the new values for rate & timebase.
12339 iPlaybackClockRate = iPlaybackClockRate_New;
12340 iOutsideTimebase = iOutsideTimebase_New;
12341
12342 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
12343 (0, "PVPlayerEngine::UpdateTimebaseAndRate() Rate %d OutsideTB 0x%x CurDir %d NewDir %d"
12344 , iPlaybackClockRate, iOutsideTimebase
12345 , iPlaybackDirection, iPlaybackDirection_New));
12346
12347 // Pause the clock if running. If already stopped or paused, the call would fail
12348 bool clockpaused = iPlaybackClock.Pause();
12349
12350 if (iOutsideTimebase)
12351 {
12352 //use the outside timebase & ignore the rate.
12353 iPlaybackClock.SetClockTimebase(*iOutsideTimebase);
12354 }
12355 else
12356 {
12357 //use the player timebase and set the rate.
12358 iPlaybackTimebase.SetRate(iPlaybackClockRate);
12359 iPlaybackClock.SetClockTimebase(iPlaybackTimebase);
12360 }
12361
12362 // Only restart the clock if the clock was paused in this function
12363 if (clockpaused)
12364 {
12365 StartPlaybackClock();
12366 }
12367 }
12368
HandleSinkNodeQueryCapConfigIF(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12369 void PVPlayerEngine::HandleSinkNodeQueryCapConfigIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12370 {
12371 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12372 (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Tick=%d", OsclTickCount::TickCount()));
12373
12374 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() In"));
12375
12376 switch (aNodeResp.GetCmdStatus())
12377 {
12378 case PVMFSuccess:
12379 {
12380 if (aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig)
12381 {
12382 aNodeContext.iEngineDatapath->iSinkNodeCapConfigIF = (PvmiCapabilityAndConfig*)aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig;
12383 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig = NULL;
12384 }
12385 }
12386 break;
12387
12388 default:
12389 {
12390 if (aNodeContext.iNode == aNodeContext.iEngineDatapath->iSinkNode)
12391 {
12392 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceCapConfig = NULL;
12393 aNodeContext.iEngineDatapath->iSinkNodeCapConfigIF = NULL;
12394 }
12395 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12396 (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Node dont support Cap-Config Interface, ignoring"));
12397 }
12398 break;
12399 }
12400
12401 // Decrement the pending counter and go to next step if 0.
12402 --iNumPendingNodeCmd;
12403 if (iNumPendingNodeCmd == 0)
12404 {
12405 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
12406 (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() All QueryInterface() commands complete"));
12407
12408 PVMFStatus cmdstatus = DoSinkNodeInit(aNodeContext.iCmdId, aNodeContext.iCmdContext);
12409 if (cmdstatus != PVMFSuccess)
12410 {
12411 bool ehPending = CheckForPendingErrorHandlingCmd();
12412 if (ehPending)
12413 {
12414 // there should be no error handling queued.
12415 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Already EH pending, should never happen"));
12416 return;
12417 }
12418 else
12419 {
12420 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12421 (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() DoSinkNodeInit failed, Add EH Command"));
12422 iCommandCompleteStatusInErrorHandling = cmdstatus;
12423 iCommandCompleteErrMsgInErrorHandling = NULL;
12424 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12425 }
12426 }
12427 }
12428
12429 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryCapConfigIF() Out"));
12430 }
12431
HandleSinkNodeInit(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12432 void PVPlayerEngine::HandleSinkNodeInit(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12433 {
12434 OSCL_UNUSED_ARG(aNodeContext);
12435 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12436 (0, "PVPlayerEngine::HandleSinkNodeInit() Tick=%d", OsclTickCount::TickCount()));
12437
12438 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInit() In"));
12439
12440 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
12441 {
12442 bool ehPending = CheckForPendingErrorHandlingCmd();
12443 if (ehPending)
12444 {
12445 // there should be no error handling queued.
12446 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeInit() Already EH pending, should never happen"));
12447 return;
12448 }
12449 else
12450 {
12451 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12452 (0, "PVPlayerEngine::HandleSinkNodeInit() cmd response is failure, Add EH Command"));
12453 PVMFErrorInfoMessageInterface* nextmsg = NULL;
12454 if (aNodeResp.GetEventExtensionInterface())
12455 {
12456 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
12457 }
12458
12459 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
12460 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkInit, puuid, nextmsg));
12461 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
12462 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12463 return;
12464 }
12465 }
12466
12467 // Decrement the pending counter and go to next step if 0.
12468 --iNumPendingNodeCmd;
12469 if (iNumPendingNodeCmd == 0)
12470 {
12471 // Init on sink nodes is complete, next step in track selection is to check with the sink nodes alone if the track is
12472 // playable or not. If track can be played using sink nodes only move to track selection or else go further to
12473 // instantiate decoder nodes for the tracks.
12474
12475 // set the Engine state to Track selection so that engine calls DoPrepare and do further processing in Track selection
12476
12477 SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_1_DONE);
12478 RunIfNotReady();
12479 }
12480
12481 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInit() Out"));
12482
12483 return;
12484 }
12485
HandleDecNodeQueryCapConfigIF(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12486 void PVPlayerEngine::HandleDecNodeQueryCapConfigIF(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12487 {
12488 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12489 (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Tick=%d", OsclTickCount::TickCount()));
12490
12491 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() In"));
12492
12493 for (uint32 i = 0; i < iTrackSelectionList.size(); i++)
12494 {
12495 switch (aNodeResp.GetCmdStatus())
12496 {
12497 case PVMFSuccess:
12498 {
12499 if (aNodeContext.iNode == iTrackSelectionList[i].iTsDecNode && iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig)
12500 {
12501 iTrackSelectionList[i].iTsDecNodeCapConfigIF = (PvmiCapabilityAndConfig*)iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig;
12502 iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
12503
12504 PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
12505 // Valid decoder node set in TrackSelectionList. Scan the TrackSelectionList further and if
12506 // any similar MIME track is present just set the decoders to NULL for now.
12507 // This is to avoid multiple Init calls on same decoder nodes for similar tracks.
12508 // Set the decoder nodes and its cap and config I/F once decoder node Inits complete.
12509 for (uint32 j = i + 1; j < iTrackSelectionList.size(); j++)
12510 {
12511 PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(j);
12512 if (!(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())))
12513 {
12514 // These were earlier set in DoDecNodeQueryCapConfifIF to avoid multiple creation of same
12515 // decoder nodes.
12516 iTrackSelectionList[j].iTsDecNode = NULL;
12517 iTrackSelectionList[j].iTsDecNodeSessionId = 0;
12518 iTrackSelectionList[j].iTsDecNodeCapConfigIF = NULL;
12519 }
12520 }
12521 }
12522 }
12523 break;
12524
12525 default:
12526 {
12527 if (aNodeContext.iNode == iTrackSelectionList[i].iTsDecNode)
12528 {
12529 iTrackSelectionList[i].iTsDecNodePVInterfaceCapConfig = NULL;
12530 iTrackSelectionList[i].iTsDecNodeCapConfigIF = NULL;
12531 }
12532 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12533 (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Node dont support Cap-Config Interface, ignoring"));
12534 }
12535 break;
12536 }
12537 }
12538
12539 // Decrement the pending counter and go to next step if 0.
12540 --iNumPendingNodeCmd;
12541 if (iNumPendingNodeCmd == 0)
12542 {
12543 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
12544 (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() All QueryInterface() commands complete"));
12545
12546 PVMFStatus cmdstatus = DoDecNodeInit(aNodeContext.iCmdId, aNodeContext.iCmdContext);
12547 if (cmdstatus != PVMFSuccess)
12548 {
12549 bool ehPending = CheckForPendingErrorHandlingCmd();
12550 if (ehPending)
12551 {
12552 // there should be no error handling queued.
12553 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Already EH pending, should never happen"));
12554 return;
12555 }
12556 else
12557 {
12558 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12559 (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() DoDecNodeInit failed, Add EH Command"));
12560 iCommandCompleteStatusInErrorHandling = cmdstatus;
12561 iCommandCompleteErrMsgInErrorHandling = NULL;
12562 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12563 }
12564 }
12565 }
12566
12567 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryCapConfigIF() Out"));
12568 }
12569
HandleDecNodeInit(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12570 void PVPlayerEngine::HandleDecNodeInit(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12571 {
12572 OSCL_UNUSED_ARG(aNodeContext);
12573 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12574 (0, "PVPlayerEngine::HandleDecNodeInit() Tick=%d", OsclTickCount::TickCount()));
12575
12576 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInit() In"));
12577
12578 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
12579 {
12580 bool ehPending = CheckForPendingErrorHandlingCmd();
12581 if (ehPending)
12582 {
12583 // there should be no error handling queued.
12584 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeInit() Already EH pending, should never happen"));
12585 return;
12586 }
12587 else
12588 {
12589 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12590 (0, "PVPlayerEngine::HandleDecNodeInit() cmd response is failure, Add EH Command"));
12591 PVMFErrorInfoMessageInterface* nextmsg = NULL;
12592 if (aNodeResp.GetEventExtensionInterface())
12593 {
12594 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
12595 }
12596
12597 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
12598 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapath, puuid, nextmsg));
12599 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
12600 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12601 return;
12602 }
12603 }
12604
12605 // Decrement the pending counter and go to next step if 0.
12606 --iNumPendingNodeCmd;
12607 if (iNumPendingNodeCmd == 0)
12608 {
12609 // All decoder node Init is complete, now set the decoder node for similar tracks in TrackSelectionList.
12610 for (uint32 i = 0; i < iTrackSelectionList.size(); i++)
12611 {
12612 PVMFTrackInfo* currTrack = iSourcePresInfoList.getTrackInfo(i);
12613
12614 for (uint32 j = i + 1; j < iTrackSelectionList.size(); j++)
12615 {
12616 // If the track has the same MIME type and needs to have a decoder node for it to be playabale track
12617 // use the already created decoder node for the track.
12618 PVMFTrackInfo* tmpTrack = iSourcePresInfoList.getTrackInfo(j);
12619
12620 if ((iTrackSelectionList[i].iTsDecNode != NULL) &&
12621 !(pv_mime_strcmp(currTrack->getTrackMimeType().get_str(), tmpTrack->getTrackMimeType().get_str())) &&
12622 !(iTrackSelectionList[j].iTsTrackValidForPlayableList))
12623 {
12624 // These were earlier set in DoDecNodeQueryCapConfifIF to avoid multiple creation of same
12625 // decoder nodes.
12626 iTrackSelectionList[j].iTsDecNode = iTrackSelectionList[i].iTsDecNode;
12627 iTrackSelectionList[j].iTsDecNodeSessionId = iTrackSelectionList[i].iTsDecNodeSessionId;
12628 iTrackSelectionList[j].iTsDecNodeCapConfigIF = iTrackSelectionList[i].iTsDecNodeCapConfigIF;
12629 }
12630 }
12631 }
12632
12633 // Now engine has all decoder and sink nodes setup for each valid track. Engine will now do the track selection based
12634 // on config paramters of each track
12635
12636 SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_2_DONE);
12637 RunIfNotReady();
12638 }
12639 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInit() Out"));
12640 return;
12641 }
12642
HandleSourceNodePrepare(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12643 void PVPlayerEngine::HandleSourceNodePrepare(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12644 {
12645 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
12646 (0, "PVPlayerEngine::HandleSourceNodePrepare() Tick=%d", OsclTickCount::TickCount()));
12647
12648 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePrepare() In"));
12649
12650 PVMFStatus cmdstatus = PVMFErrNotSupported;
12651
12652 switch (aNodeResp.GetCmdStatus())
12653 {
12654 case PVMFSuccess:
12655 {
12656 // Datapaths are already set during intelligent track selection, just query for optional interfaces.
12657 iNumPendingDatapathCmd = 0;
12658 for (uint32 i = 0; i < iDatapathList.size(); ++i)
12659 {
12660 if (iDatapathList[i].iTrackInfo != NULL)
12661 {
12662 PVMFStatus retcode = DoSinkNodeQueryInterfaceOptional(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
12663 if (retcode == PVMFSuccess)
12664 {
12665 ++iNumPendingDatapathCmd;
12666 cmdstatus = PVMFSuccess;
12667 }
12668 else
12669 {
12670 cmdstatus = retcode;
12671 }
12672 }
12673 }
12674
12675 if (iNumPendingDatapathCmd == 0)
12676 {
12677 if (cmdstatus == PVMFErrNotSupported)
12678 {
12679 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePrepare() No datapath could be setup. Asserting"));
12680 OSCL_ASSERT(false);
12681 }
12682 bool ehPending = CheckForPendingErrorHandlingCmd();
12683 if (ehPending)
12684 {
12685 // there should be no error handling queued.
12686 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePrepare() Already EH pending, should never happen"));
12687 return;
12688 }
12689 else
12690 {
12691 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12692 (0, "PVPlayerEngine::HandleSourceNodePrepare() Report command as failed, Add EH Command"));
12693 iCommandCompleteStatusInErrorHandling = cmdstatus;
12694 iCommandCompleteErrMsgInErrorHandling = NULL;
12695 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12696 }
12697 }
12698 }
12699 break;
12700
12701 default:
12702 {
12703 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12704 (0, "PVPlayerEngine::HandleSourceNodePrepare() failed, Add EH Command"));
12705 bool ehPending = CheckForPendingErrorHandlingCmd();
12706 if (ehPending)
12707 {
12708 // there should be no error handling queued.
12709 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePrepare() Already EH pending, should never happen"));
12710 return;
12711 }
12712 PVMFErrorInfoMessageInterface* nextmsg = NULL;
12713 if (aNodeResp.GetEventExtensionInterface())
12714 {
12715 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
12716 }
12717
12718 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
12719 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
12720 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
12721
12722 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12723 }
12724 break;
12725 }
12726
12727 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePrepare() Out"));
12728 }
12729
HandleSinkNodeQueryInterfaceOptional(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12730 void PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12731 {
12732 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12733 (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
12734
12735 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
12736
12737 // Determine QueryInterface() for which interface completed
12738 if (aNodeContext.iCmdType == PVP_CMD_SinkNodeQuerySyncCtrlIF)
12739 {
12740 if (aNodeResp.GetCmdStatus() == PVMFSuccess && aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl)
12741 {
12742 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF = (PvmfNodesSyncControlInterface*)aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl;
12743 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl = NULL;
12744
12745 // Pass the playback clock to the sync control
12746 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetClock(&iPlaybackClock);
12747
12748 // Set the sync margin, find corresponding track for the datapath using mime string
12749 bool videoTrack = false;
12750 bool audioTrack = false;
12751 bool textTrack = false;
12752 bool retVal = FindTrackForDatapathUsingMimeString(videoTrack, audioTrack, textTrack, aNodeContext.iEngineDatapath);
12753 if (textTrack && retVal)
12754 {
12755 // Text track
12756 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginText.min), iSyncMarginText.max);
12757 }
12758 else if (audioTrack && retVal)
12759 {
12760 // Audio track
12761 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginAudio.min), iSyncMarginAudio.max);
12762 }
12763 else
12764 {
12765 // Video track available or an unknown datapath
12766 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginVideo.min), iSyncMarginVideo.max);
12767 }
12768 }
12769 else
12770 {
12771 // sync control interface is not available in this sink node
12772 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceSyncCtrl = NULL;
12773 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF = NULL;
12774 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Metadata IF not available"));
12775 OSCL_ASSERT(false);
12776 }
12777 }
12778 else if (aNodeContext.iCmdType == PVP_CMD_SinkNodeQueryMetadataIF)
12779 {
12780 if (aNodeResp.GetCmdStatus() == PVMFSuccess && aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt)
12781 {
12782 aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF = (PVMFMetadataExtensionInterface*)aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt;
12783 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt = NULL;
12784
12785 // Add the video sink node's metadata extension IF to the list
12786 if (AddToMetadataInterfaceList(aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF, aNodeContext.iEngineDatapath->iSinkNodeSessionId, aNodeContext.iEngineDatapath, aNodeContext.iEngineDatapath->iSinkNode) != PVMFSuccess)
12787 {
12788 aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF->removeRef();
12789 aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF = NULL;
12790 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Metadata IF could not be added to list"));
12791 }
12792 }
12793 else
12794 {
12795 // Metadata is not available in this video sink node
12796 aNodeContext.iEngineDatapath->iSinkNodePVInterfaceMetadataExt = NULL;
12797 aNodeContext.iEngineDatapath->iSinkNodeMetadataExtIF = NULL;
12798 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Metadata IF not available"));
12799 }
12800 }
12801 else
12802 {
12803 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Unknown cmd type. Asserting"));
12804 OSCL_ASSERT(false);
12805 }
12806
12807 // Decrement the pending counter and go to next step if 0.
12808 --aNodeContext.iEngineDatapath->iNumPendingCmd;
12809 if (aNodeContext.iEngineDatapath->iNumPendingCmd == 0)
12810 {
12811 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() All QueryInterface() commands complete"));
12812
12813 // Create the decoder node if necessary
12814 PVMFStatus cmdstatus = DoDecNodeQueryInterfaceOptional(*(aNodeContext.iEngineDatapath), aNodeContext.iCmdId, aNodeContext.iCmdContext);
12815 if (cmdstatus == PVMFErrNotSupported)
12816 {
12817 cmdstatus = DoDatapathPrepare(*(aNodeContext.iEngineDatapath), aNodeContext.iCmdId, aNodeContext.iCmdContext);
12818 }
12819
12820 if (cmdstatus != PVMFSuccess)
12821 {
12822 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12823 (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Report command as failed, Add EH Command"));
12824 bool ehPending = CheckForPendingErrorHandlingCmd();
12825 if (ehPending)
12826 {
12827 // there should be no error handling queued.
12828 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Already EH pending, should never happen"));
12829 return;
12830 }
12831 else
12832 {
12833 iCommandCompleteStatusInErrorHandling = cmdstatus;
12834 iCommandCompleteErrMsgInErrorHandling = NULL;
12835 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12836 }
12837 }
12838 }
12839
12840 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeQueryInterfaceOptional() Out"));
12841 }
12842
HandleSinkNodeDecNodeReset(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12843 void PVPlayerEngine::HandleSinkNodeDecNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12844 {
12845 OSCL_UNUSED_ARG(aNodeContext);
12846 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12847 (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() Tick=%d", OsclTickCount::TickCount()));
12848
12849 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() In"));
12850
12851 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
12852 {
12853 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12854 (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() Reset failed, assert"));
12855 OSCL_ASSERT(false);
12856 return;
12857 }
12858
12859 // Decrement the pending counter and go to next step if 0.
12860 --iNumPendingNodeCmd;
12861 if (iNumPendingNodeCmd == 0)
12862 {
12863 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() All Sinknode and decnode Reset() commands complete"));
12864 SetEngineState(PVP_ENGINE_STATE_TRACK_SELECTION_3_DONE);
12865 RunIfNotReady();
12866 }
12867
12868 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeDecNodeReset() Out"));
12869 }
12870
HandleDecNodeQueryInterfaceOptional(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12871 void PVPlayerEngine::HandleDecNodeQueryInterfaceOptional(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12872 {
12873 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_STACK_TRACE,
12874 (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Tick=%d", OsclTickCount::TickCount()));
12875
12876 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
12877
12878 // Determine QueryInterface() for which interface completed
12879 if (aNodeContext.iCmdType == PVP_CMD_DecNodeQueryMetadataIF)
12880 {
12881 if (aNodeResp.GetCmdStatus() == PVMFSuccess && aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt)
12882 {
12883 aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF = (PVMFMetadataExtensionInterface*)aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt;
12884 aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt = NULL;
12885
12886 // Add the video dec node's metadata extension IF to the list
12887 if (AddToMetadataInterfaceList(aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF, aNodeContext.iEngineDatapath->iDecNodeSessionId, aNodeContext.iEngineDatapath, aNodeContext.iEngineDatapath->iDecNode) != PVMFSuccess)
12888 {
12889 aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF->removeRef();
12890 aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF = NULL;
12891
12892 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Metadata IF could not be added to list"));
12893 }
12894 }
12895 else
12896 {
12897 // Metadata is not available in this dec node
12898 aNodeContext.iEngineDatapath->iDecNodePVInterfaceMetadataExt = NULL;
12899 aNodeContext.iEngineDatapath->iDecNodeMetadataExtIF = NULL;
12900 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Metadata IF not available"));
12901 }
12902 }
12903 else
12904 {
12905 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Unknown cmd type. Asserting"));
12906 OSCL_ASSERT(false);
12907 }
12908
12909 if (aNodeContext.iEngineDatapath->iDecNodeCapConfigIF)
12910 {
12911 // Configure the dec node for player use
12912 PvmiKvp kvpparam;
12913 PvmiKvp* retkvp = NULL;
12914 OSCL_StackString<64> kvpparamkey;
12915
12916 bool videoTrack = false;
12917 bool audioTrack = false;
12918 bool textTrack = false;
12919 bool retVal = FindTrackForDatapathUsingMimeString(videoTrack, audioTrack, textTrack, aNodeContext.iEngineDatapath);
12920 if (videoTrack && retVal)
12921 {
12922 // Video track
12923 // Disable drop frame mode
12924 kvpparamkey = _STRLIT_CHAR("x-pvmf/video/decoder/dropframe_enable;valtype=bool");
12925 kvpparam.value.bool_value = false;
12926 }
12927 else if (audioTrack && retVal)
12928 {
12929 // Audio track
12930 // Disable silence insertion
12931 kvpparamkey = _STRLIT_CHAR("x-pvmf/audio/decoder/silenceinsertion_enable;valtype=bool");
12932 kvpparam.value.bool_value = false;
12933 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->SetMargins((-1*iSyncMarginAudio.min), iSyncMarginAudio.max);
12934 }
12935
12936 if (kvpparamkey.get_size() > 0)
12937 {
12938 kvpparam.key = kvpparamkey.get_str();
12939 aNodeContext.iEngineDatapath->iDecNodeCapConfigIF->setParametersSync(NULL, &kvpparam, 1, retkvp);
12940 if (retkvp != NULL)
12941 {
12942 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Configuring dec node for player use via cap-config IF failed"));
12943 }
12944 }
12945 }
12946
12947 // Decrement the pending counter and go to next step if 0.
12948 OSCL_ASSERT(aNodeContext.iEngineDatapath->iNumPendingCmd > 0);
12949 --aNodeContext.iEngineDatapath->iNumPendingCmd;
12950 if (aNodeContext.iEngineDatapath->iNumPendingCmd == 0)
12951 {
12952 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() All QueryInterface() commands complete"));
12953
12954 // Prepare the datapath
12955 PVMFStatus cmdstatus = DoDatapathPrepare(*(aNodeContext.iEngineDatapath), aNodeContext.iCmdId, aNodeContext.iCmdContext);
12956
12957 if (cmdstatus != PVMFSuccess)
12958 {
12959 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12960 (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Report command as failed, Add EH command"));
12961 bool ehPending = CheckForPendingErrorHandlingCmd();
12962 if (ehPending)
12963 {
12964 // there should be no error handling queued.
12965 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Already EH pending, should never happen"));
12966 return;
12967 }
12968 else
12969 {
12970 iCommandCompleteStatusInErrorHandling = cmdstatus;
12971 iCommandCompleteErrMsgInErrorHandling = NULL;
12972 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
12973 }
12974 }
12975 }
12976
12977 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeQueryInterfaceOptional() Out"));
12978 }
12979
12980
HandleSourceNodeQueryDataSourcePosition(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)12981 void PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
12982 {
12983 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() In"));
12984
12985 PVMFTimestamp requesttime = iTargetNPT;
12986
12987 if (aNodeResp.GetCmdStatus() == PVMFErrNotSupported || aNodeResp.GetCmdStatus() == PVMFErrArgument)
12988 {
12989 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() QueryDataSourcePosition failed. Assume position goes to requested position"));
12990 }
12991 else if (aNodeResp.GetCmdStatus() != PVMFSuccess)
12992 {
12993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
12994 (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() QueryDataSourcePosition failed, Add EH command"));
12995 bool ehPending = CheckForPendingErrorHandlingCmd();
12996 if (ehPending)
12997 {
12998 // there should be no error handling queued.
12999 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePause() Already EH pending, should never happen"));
13000 return;
13001 }
13002 PVMFErrorInfoMessageInterface* nextmsg = NULL;
13003 if (aNodeResp.GetEventExtensionInterface())
13004 {
13005 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
13006 }
13007
13008 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13009 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
13010 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
13011
13012 if (iState == PVP_ENGINE_STATE_PREPARING)
13013 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
13014 else if (iState == PVP_ENGINE_STATE_RESUMING)
13015 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
13016 return;
13017 }
13018 else
13019 {
13020 PVMFNodeCapability nodeCapability;
13021 iSourceNode->GetCapability(nodeCapability);
13022 PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
13023 bool mpeg4FormatType = false;
13024 if (formatType != NULL)
13025 {
13026 if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
13027 {
13028 mpeg4FormatType = true;
13029 }
13030 else
13031 {
13032 mpeg4FormatType = false;
13033 }
13034 }
13035
13036 if (mpeg4FormatType)
13037 {
13038 // Every thing is OK.. Calculate the modified target position depending upon nearest before and after syncPoints.
13039 // For MPEG4 files
13040 CalculateActualPlaybackPosition();
13041 }
13042 }
13043
13044 // Determine the SetDataSourcePosition parameter based on query result and reposition settings
13045 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
13046 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition()"
13047 "Requested NPT %d, Modified Target NPT %d", requesttime, iTargetNPT));
13048
13049 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0,
13050 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition()"
13051 "Requested NPT %d, Modified Target NPT %d", requesttime, iTargetNPT));
13052
13053 uint32 startOfSeekWindow = 0;
13054 if (requesttime > iSyncPointSeekWindow)
13055 {
13056 startOfSeekWindow = (requesttime - iSyncPointSeekWindow);
13057 }
13058 uint32 endOfSeekWindow = requesttime + iSyncPointSeekWindow;
13059
13060 // 1) Check if the modified target position falls within the window
13061 if ((iTargetNPT >= startOfSeekWindow) &&
13062 (iTargetNPT <= endOfSeekWindow))
13063 {
13064 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
13065 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
13066 "RequestedNPT(%d) ModifiedTargetNPT(%d) is in the window (%d, %d), Seeking To %d",
13067 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, iTargetNPT));
13068
13069 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0,
13070 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
13071 "RequestedNPT(%d) ModifiedTargetNPT(%d) is in the window (%d, %d), Seeking To %d",
13072 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, iTargetNPT));
13073
13074 requesttime = iTargetNPT;
13075 }
13076 else
13077 {
13078 // 1) Check if the actual seek point is before the window start, then set the
13079 // request time to start of the window
13080 // 2) Check if the actual seek point is after the window end, then
13081 // go back to start of the seek window
13082 // SFR is not really an option here since we are not playing yet, therefore always
13083 // go to start of the window
13084 if ((iTargetNPT < startOfSeekWindow) ||
13085 (iTargetNPT > endOfSeekWindow))
13086 {
13087 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
13088 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
13089 "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt False",
13090 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
13091
13092 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0,
13093 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
13094 "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt False",
13095 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
13096
13097 requesttime = startOfSeekWindow;
13098 iTargetNPT = requesttime;
13099 }
13100 else
13101 {
13102 //error
13103 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0,
13104 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() - "
13105 "RequestedNPT(%d) ModifiedTargetNPT(%d) window (%d, %d), Error Condition Asserting",
13106 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow));
13107 OSCL_ASSERT(false);
13108 }
13109 }
13110
13111 // Do the source positioning
13112 PVMFStatus retval = DoSourceNodeSetDataSourcePosition(aNodeContext.iCmdId, aNodeContext.iCmdContext);
13113 if (retval != PVMFSuccess)
13114 {
13115 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13116 (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() Report command as failed, Add EH command"));
13117 bool ehPending = CheckForPendingErrorHandlingCmd();
13118 if (ehPending)
13119 {
13120 // there should be no error handling queued.
13121 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() Already EH pending, should never happen"));
13122 return;
13123 }
13124 else
13125 {
13126 iCommandCompleteStatusInErrorHandling = retval;
13127 iCommandCompleteErrMsgInErrorHandling = NULL;
13128 if (iState == PVP_ENGINE_STATE_PREPARING)
13129 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
13130 else if (iState == PVP_ENGINE_STATE_RESUMING)
13131 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
13132 }
13133 }
13134
13135 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePosition() Out"));
13136 }
13137
13138
HandleSourceNodeSetDataSourcePosition(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)13139 void PVPlayerEngine::HandleSourceNodeSetDataSourcePosition(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
13140 {
13141 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() In"));
13142
13143 PVMFStatus cmdstatus = PVMFFailure;
13144
13145 switch (aNodeResp.GetCmdStatus())
13146 {
13147 case PVMFErrArgument:
13148 case PVMFErrNotSupported:
13149 {
13150 if (iChangePlaybackPositionWhenResuming)
13151 {
13152 PVPPlaybackPosition curpos;
13153 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13154 GetPlaybackClockPosition(curpos);
13155 uint32 clockcurpos = 0;
13156 bool tmpbool = false;
13157 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
13158
13159 // since repositioning is not supported and if the playback position change request was
13160 // issued during paused state, then continue from paused position.
13161 iChangePlaybackPositionWhenResuming = false;
13162 iWatchDogTimerInterval = 0;
13163 iActualNPT = curpos.iPosValue.millisec_value;
13164 iActualMediaDataTS = clockcurpos;
13165 iSkipMediaDataTS = clockcurpos;
13166
13167 iStartNPT = iActualNPT;
13168 iStartMediaDataTS = iSkipMediaDataTS;
13169
13170 // also decrement the stream id as no skip will be called on MIO node.
13171 --iStreamID;
13172
13173 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13174 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
13175 SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
13176 infomsg->removeRef();
13177 }
13178 else
13179 {
13180 // This happens when we are in preparing state
13181 // Since this repositioning was not supported, assume the playback
13182 // will start from time 0
13183 iWatchDogTimerInterval = 0;
13184 iActualNPT = 0;
13185 iActualMediaDataTS = 0;
13186 iSkipMediaDataTS = 0;
13187 // Then continue to handle like success case
13188 iStartNPT = 0;
13189 iStartMediaDataTS = 0;
13190 }
13191
13192 // Save the actual starting position for GetPlaybackRange() query
13193 iTargetNPT = iActualNPT;
13194 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
13195 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13196 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13197 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Requested begin position(%d ms) is not supported so start from prev location.",
13198 iTargetNPT));
13199 }
13200 break;
13201
13202 case PVMFSuccess:
13203 {
13204 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13205 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() SetDataSourcePosition() successful. StartMediaTS %d ms, ActualNPT %d ms, TargetNPT %d ms",
13206 iActualMediaDataTS, iActualNPT, iTargetNPT));
13207 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
13208 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() SetDataSourcePosition() successful. StartMediaTS %d ms, ActualNPT %d ms, TargetNPT %d ms",
13209 iActualMediaDataTS, iActualNPT, iTargetNPT));
13210 // Compute the difference between actualNPT and targetNPT before any adjustments
13211 if (iTargetNPT >= iActualNPT)
13212 {
13213 iWatchDogTimerInterval = iTargetNPT - iActualNPT;
13214 }
13215
13216 // Determine if adjustment needed to skip to requested time
13217 if (iSkipToRequestedPosition && (iActualNPT < iTargetNPT))
13218 {
13219 if (iTargetNPT - iActualNPT > iNodeDataQueuingTimeout)
13220 {
13221 // Sync point seems to be far away in the stream
13222 // Can't adjust the skip time back so use the returned values to skip to
13223 iSkipMediaDataTS = iActualMediaDataTS;
13224 iTargetNPT = iActualNPT;
13225 iWatchDogTimerInterval = 0;
13226 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
13227 }
13228 else
13229 {
13230 //check if source node wants to override
13231 uint32 startNPTFrmSource = iActualNPT;
13232 if (iSourceNodePBCtrlIF->ComputeSkipTimeStamp(iTargetNPT,
13233 iActualNPT,
13234 iActualMediaDataTS,
13235 iSkipMediaDataTS,
13236 startNPTFrmSource) == PVMFSuccess)
13237 {
13238 iWatchDogTimerInterval = startNPTFrmSource - iActualNPT;
13239 iActualNPT = startNPTFrmSource;
13240 iTargetNPT = iActualNPT;
13241 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
13242 }
13243 else
13244 {
13245 // Adjust the media data time to skip-to to correspond to the requested time
13246 // Add the difference of target NPT with actual playback position in NPT to the actual media data time to get time to skip to.
13247 iSkipMediaDataTS = iActualMediaDataTS + (iTargetNPT - iActualNPT);
13248 iActualNPT = iTargetNPT;
13249 }
13250 }
13251 }
13252 else
13253 {
13254 // Can't adjust the skip time back so use the returned values to skip to
13255 iSkipMediaDataTS = iActualMediaDataTS;
13256 iTargetNPT = iActualNPT;
13257 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
13258 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13259 iWatchDogTimerInterval = 0;
13260 }
13261
13262 // Save initial NTP and TS values
13263 iStartNPT = iActualNPT;
13264 iStartMediaDataTS = iSkipMediaDataTS;
13265
13266 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13267 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() After adjustment StartMediaTS %d ms, AdjustedMediaTS %d ms, ActualPBPos %d ms Start NPT %d Start TS %d",
13268 iActualMediaDataTS, iSkipMediaDataTS, iActualNPT, iStartNPT, iStartMediaDataTS));
13269 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
13270 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() After adjustment StartMediaTS %d ms, AdjustedMediaTS %d ms, ActualNPT %d ms StartNPT %d StartTS %d",
13271 iActualMediaDataTS, iSkipMediaDataTS, iActualNPT, iStartNPT, iStartMediaDataTS));
13272 }
13273 break;
13274
13275 default:
13276 {
13277 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13278 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() failed, Add EH command"));
13279 bool ehPending = CheckForPendingErrorHandlingCmd();
13280 if (ehPending)
13281 {
13282 // there should be no error handling queued.
13283 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Already EH pending, should never happen"));
13284 return;
13285 }
13286 PVMFErrorInfoMessageInterface* nextmsg = NULL;
13287 if (aNodeResp.GetEventExtensionInterface())
13288 {
13289 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
13290 }
13291
13292 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13293 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
13294 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
13295
13296 if (iState == PVP_ENGINE_STATE_PREPARING)
13297 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
13298 else if (iState == PVP_ENGINE_STATE_RESUMING)
13299 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
13300
13301 return;
13302 }
13303 }
13304 // Repositioning so reset the EOS flag for each active datapath
13305 for (uint32 i = 0; i < iDatapathList.size(); ++i)
13306 {
13307 if (iDatapathList[i].iDatapath)
13308 {
13309 iDatapathList[i].iEndOfDataReceived = false;
13310 }
13311 }
13312
13313 // Contine on and start the source node
13314 cmdstatus = DoSourceNodeStart(aNodeContext.iCmdId, aNodeContext.iCmdContext);
13315 if (cmdstatus != PVMFSuccess)
13316 {
13317 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Report command as failed, Add EH command"));
13318 bool ehPending = CheckForPendingErrorHandlingCmd();
13319 if (ehPending)
13320 {
13321 // there should be no error handling queued.
13322 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Already EH pending, should never happen"));
13323 return;
13324 }
13325 else
13326 {
13327 iCommandCompleteStatusInErrorHandling = cmdstatus;
13328 iCommandCompleteErrMsgInErrorHandling = NULL;
13329 if (iState == PVP_ENGINE_STATE_PREPARING)
13330 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
13331 else if (iState == PVP_ENGINE_STATE_RESUMING)
13332 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
13333 }
13334 }
13335
13336 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Out"));
13337 }
13338
HandleSourceNodeSetDataSourceDirection(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)13339 void PVPlayerEngine::HandleSourceNodeSetDataSourceDirection(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
13340 {
13341 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() In"));
13342
13343 if (iChangePlaybackDirectionWhenResuming)
13344 {
13345 // Continuation of Engine Resume sequence.
13346
13347 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Context RESUME"));
13348 PVMFStatus cmdstatus = PVMFFailure;
13349
13350 switch (aNodeResp.GetCmdStatus())
13351 {
13352 case PVMFErrArgument:
13353 case PVMFErrNotSupported:
13354 {
13355 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13356 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Requested direction is not supported!"));
13357 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13358 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoChangePlaybackPositionNotSupported, puuid, NULL));
13359 SendInformationalEvent(PVMFInfoChangePlaybackPositionNotSupported, OSCL_STATIC_CAST(PVInterface*, infomsg));
13360 infomsg->removeRef();
13361 }
13362 break;
13363
13364 case PVMFSuccess:
13365 {
13366 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13367 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() SetDataSourceDirection() successful. StartMediaTS %d ms, ActualPBPos %d ms",
13368 iActualMediaDataTS, iActualNPT));
13369
13370 //there's no adjustment to the media TS here.
13371 iSkipMediaDataTS = iActualMediaDataTS;
13372 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
13373 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13374
13375 //Install the new direction and get the repositioning target.
13376 UpdateDirection(iActualNPT, iSkipMediaDataTS, iChangeDirectionNPT);
13377
13378 //Reposition the source to the desired playback time
13379 if (!iChangeDirectionNPT.iIndeterminate)
13380 {
13381 iChangePlaybackDirectionWhenResuming = false;
13382 iChangePlaybackPositionWhenResuming = true;
13383 PVPlayerEngineCommand cmd(0, aNodeContext.iCmdId, aNodeContext.iCmdContext, NULL, false);
13384 iCurrentBeginPosition = iChangeDirectionNPT;
13385 PVMFStatus retval = UpdateCurrentBeginPosition(iCurrentBeginPosition, cmd);
13386 if (retval == PVMFPending)
13387 {
13388 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Repos to %d started", iChangeDirectionNPT.iPosValue));
13389 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
13390 return;//wait on the repos sequence...
13391 }
13392 else if (retval != PVMFSuccess)
13393 {
13394 //else can't reposition, ignore failure and continue.
13395 iChangeDirectionNPT.iIndeterminate = true;
13396 iChangePlaybackPositionWhenResuming = false;
13397 //need to leave the flag set for later in HandleDatapathResume,
13398 //to trigger the skip media data.
13399 iChangePlaybackDirectionWhenResuming = true;
13400 }
13401 }
13402 }
13403 break;
13404
13405 default:
13406 {
13407 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13408 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() failed, Add EH command"));
13409 bool ehPending = CheckForPendingErrorHandlingCmd();
13410 if (ehPending)
13411 {
13412 // there should be no error handling queued.
13413 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Already EH pending, should never happen"));
13414 return;
13415 }
13416 PVMFErrorInfoMessageInterface* nextmsg = NULL;
13417 if (aNodeResp.GetEventExtensionInterface())
13418 {
13419 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
13420 }
13421
13422 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13423 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
13424 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
13425 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
13426 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
13427 return;
13428 }
13429 }
13430
13431
13432 // Repositioning so reset the EOS flag for each active datapath
13433 for (uint32 i = 0; i < iDatapathList.size(); ++i)
13434 {
13435 if (iDatapathList[i].iDatapath)
13436 {
13437 iDatapathList[i].iEndOfDataReceived = false;
13438 }
13439 }
13440
13441 // Start the source node.
13442 cmdstatus = DoSourceNodeStart(aNodeContext.iCmdId, aNodeContext.iCmdContext);
13443 if (cmdstatus != PVMFSuccess)
13444 {
13445 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13446 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePosition() Report command as failed, Add EH command"));
13447 bool ehPending = CheckForPendingErrorHandlingCmd();
13448 if (ehPending)
13449 {
13450 // there should be no error handling queued.
13451 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Already EH pending, should never happen"));
13452 return;
13453 }
13454 else
13455 {
13456 iCommandCompleteStatusInErrorHandling = cmdstatus;
13457 iCommandCompleteErrMsgInErrorHandling = NULL;
13458 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
13459 }
13460 }
13461 }
13462 else
13463 {
13464 //Continuation of SetPlaybackRate sequence.
13465
13466 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Context SETPLAYBACKRATE"));
13467
13468 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
13469 {
13470 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() SetDataSourceDirection failed. Playback position change has been cancelled"));
13471
13472 if (aNodeResp.GetCmdStatus() == PVMFErrNotSupported || aNodeResp.GetCmdStatus() == PVMFErrArgument)
13473 {
13474 // For non-fatal error, continue playback by resuming the clock
13475 StartPlaybackClock();
13476 }
13477 else
13478 {
13479 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13480 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() failed, Add EH command"));
13481 // Initiate error handling
13482 bool ehPending = CheckForPendingErrorHandlingCmd();
13483 if (ehPending)
13484 {
13485 // there should be no error handling queued.
13486 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Already EH pending, should never happen"));
13487 return;
13488 }
13489 PVMFErrorInfoMessageInterface* nextmsg = NULL;
13490 if (aNodeResp.GetEventExtensionInterface())
13491 {
13492 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
13493 }
13494
13495 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13496 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
13497 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
13498 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE, NULL, NULL, NULL, false);
13499 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
13500 return;
13501 }
13502
13503 PVMFErrorInfoMessageInterface* nextmsg = NULL;
13504 if (aNodeResp.GetEventExtensionInterface() != NULL)
13505 {
13506 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
13507 }
13508 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13509 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
13510
13511 // Complete the SetPlaybackRate() command as failed
13512 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, aNodeResp.GetCmdStatus(), OSCL_STATIC_CAST(PVInterface*, errmsg));
13513
13514 errmsg->removeRef();
13515 errmsg = NULL;
13516 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
13517 return;
13518 }
13519
13520 // no adjustement here.
13521 iSkipMediaDataTS = iActualMediaDataTS;
13522 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
13523 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13524
13525 //Install the new direction and get the repositioning target
13526 UpdateDirection(iActualNPT, iSkipMediaDataTS, iChangeDirectionNPT);
13527
13528 //Launch a repositioning sequence now.
13529 if (!iChangeDirectionNPT.iIndeterminate)
13530 {
13531 PVPlayerEngineCommand cmd(0, aNodeContext.iCmdId, aNodeContext.iCmdContext, NULL, false);
13532 iCurrentBeginPosition = iChangeDirectionNPT;
13533 PVMFStatus retval = UpdateCurrentBeginPosition(iCurrentBeginPosition, cmd);
13534 if (retval == PVMFPending)
13535 {
13536 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Repos to %d started", iChangeDirectionNPT.iPosValue));
13537 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
13538 return;//wait on the repos sequence...
13539 }
13540 else if (retval != PVMFSuccess)
13541 {
13542 //the direction is already changed, so just ignore this failure and continue
13543 iChangeDirectionNPT.iIndeterminate = true;
13544 }
13545 }
13546
13547 // Repositioning so reset the EOS flag for each active datapath
13548 for (uint32 i = 0; i < iDatapathList.size(); ++i)
13549 {
13550 if (iDatapathList[i].iDatapath)
13551 {
13552 iDatapathList[i].iEndOfDataReceived = false;
13553 }
13554 }
13555
13556 // Skip to the new source node position, so that all the data that was queued
13557 // when the command was received will get flushed.
13558
13559 PVMFStatus retval = DoSinkNodeSkipMediaDataDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext);
13560 if (retval != PVMFSuccess)
13561 {
13562 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Skipping media data request in sink nodes failed. Repositioning did not complete."));
13563 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13564 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSink, puuid, NULL));
13565
13566 //clear the pending direction change NPT.
13567 iChangeDirectionNPT.iIndeterminate = true;
13568
13569 // Complete the SetPlaybackRate() command as failed
13570 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval, OSCL_STATIC_CAST(PVInterface*, errmsg));
13571
13572 errmsg->removeRef();
13573 errmsg = NULL;
13574 }
13575 // else wait on HandleSinkNodeSkipMediaDataDuringPlayback.
13576 }
13577 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourceDirection() Out"));
13578 }
13579
HandleSourceNodeStart(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)13580 void PVPlayerEngine::HandleSourceNodeStart(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
13581 {
13582 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
13583 (0, "PVPlayerEngine::HandleSourceNodeStart() Tick=%d", OsclTickCount::TickCount()));
13584
13585 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStart() In"));
13586
13587 PVMFStatus cmdstatus = PVMFErrNotSupported;
13588
13589 switch (aNodeResp.GetCmdStatus())
13590 {
13591 case PVMFSuccess:
13592 {
13593 // Issue Skip on Sink Node and Start on datapaths back to back. This is done to make sure that
13594 // sink node is started only after discarding the data from an earlier stream.
13595 cmdstatus = DoSinkNodeSkipMediaData(aNodeContext.iCmdId, aNodeContext.iCmdContext);
13596 if (cmdstatus != PVMFSuccess)
13597 {
13598 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStart() Skip of sink node did a leave, asserting"));
13599 OSCL_ASSERT(false);
13600 }
13601
13602 // Start the available datapaths
13603 iNumPendingDatapathCmd = 0;
13604 for (uint32 i = 0; i < iDatapathList.size(); ++i)
13605 {
13606 if (iDatapathList[i].iDatapath)
13607 {
13608 PVMFStatus retval = DoDatapathStart(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
13609 if (retval == PVMFSuccess)
13610 {
13611 ++iNumPendingDatapathCmd;
13612 cmdstatus = PVMFSuccess;
13613 }
13614 else
13615 {
13616 cmdstatus = retval;
13617 break;
13618 }
13619 }
13620 }
13621 if (iNumPendingDatapathCmd == 0)
13622 {
13623 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13624 (0, "PVPlayerEngine:HandleSourceNodeStart() DoDatapathStart failed, Add EH command"));
13625 bool ehPending = CheckForPendingErrorHandlingCmd();
13626 if (ehPending)
13627 {
13628 // there should be no error handling queued.
13629 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine:HandleSourceNodeStart() Already EH pending, should never happen"));
13630 return;
13631 }
13632 iCommandCompleteStatusInErrorHandling = cmdstatus;
13633 iCommandCompleteErrMsgInErrorHandling = NULL;
13634 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
13635 }
13636 }
13637 break;
13638
13639 default:
13640 {
13641 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
13642 (0, "PVPlayerEngine:HandleSourceNodeStart() failed, Add EH command"));
13643 bool ehPending = CheckForPendingErrorHandlingCmd();
13644 if (ehPending)
13645 {
13646 // there should be no error handling queued.
13647 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine:HandleSourceNodeStart() Already EH pending, should never happen"));
13648 return;
13649 }
13650 PVMFErrorInfoMessageInterface* nextmsg = NULL;
13651 if (aNodeResp.GetEventExtensionInterface())
13652 {
13653 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
13654 }
13655
13656 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13657 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
13658 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
13659 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
13660 }
13661 break;
13662 }
13663
13664 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStart() Out"));
13665 }
13666
13667
HandleSinkNodeSkipMediaData(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)13668 void PVPlayerEngine::HandleSinkNodeSkipMediaData(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
13669 {
13670 OSCL_UNUSED_ARG(aNodeContext);
13671 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
13672 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() for %s Tick=%d",
13673 aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
13674
13675 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
13676 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() for %s, iNumPVMFInfoStartOfDataPending=%d",
13677 aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), iNumPVMFInfoStartOfDataPending));
13678
13679 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13680 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() In"));
13681
13682 --iNumPendingNodeCmd;
13683
13684 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
13685 {
13686 // Sink node report error with SkipMediaData()
13687 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() Sink node report error for SkipMediaData(). Asserting"));
13688 OSCL_ASSERT(false);
13689 }
13690
13691 --iNumPendingSkipCompleteEvent;
13692
13693 if (iNumPendingNodeCmd == 0)
13694 {
13695 // We dont start the playback clock here since engine is waiting for Start on Sink nodes to complete
13696 // This will also check the order in which Sink Node completes the command. Sinks should complete Skip
13697 // first and then Start, therefore iNumPendingDatapathCmd should always be greater than zero when
13698 // this happens. If not just assert.
13699 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
13700 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() Skip Complete"));
13701 }
13702
13703 if ((iNumPendingSkipCompleteEvent == 0) && (iNumPVMFInfoStartOfDataPending == 0))
13704 {
13705 // we have received all the bos event so cancel the watchDogTimer if any.
13706 if (iWatchDogTimer->IsBusy())
13707 {
13708 iWatchDogTimer->Cancel();
13709 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData - WatchDogTimer cancelled"));
13710 }
13711 }
13712
13713 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaData() Out"));
13714 }
13715
13716
HandleSourceNodeQueryDataSourcePositionDuringPlayback(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)13717 void PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
13718 {
13719 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() In"));
13720
13721 PVMFTimestamp requesttime = iTargetNPT;
13722 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
13723 {
13724 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() QueryDataSourcePosition failed. Assume position goes to requested position"));
13725 }
13726 else
13727 {
13728 PVMFNodeCapability nodeCapability;
13729 iSourceNode->GetCapability(nodeCapability);
13730 PVMFFormatType * formatType = nodeCapability.iInputFormatCapability.begin();
13731 bool mpeg4FormatType = false;
13732 if (formatType != NULL)
13733 {
13734 if ((pv_mime_strcmp((char*)formatType->getMIMEStrPtr(), PVMF_MIME_MPEG4FF)) == 0)
13735 {
13736 mpeg4FormatType = true;
13737 }
13738 else
13739 {
13740 mpeg4FormatType = false;
13741 }
13742 }
13743 if (mpeg4FormatType)
13744 {
13745 // Every thing is OK.. Calculate the modified target position depending upon nearest before and after syncPoints.
13746 // For MPEG4 files
13747 CalculateActualPlaybackPosition();
13748 }
13749 }
13750
13751 // Determine the SetDataSourcePosition parameter based on query result and reposition settings
13752 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
13753 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback()"
13754 "Requested NPT %d, ModifiedTarget NPT %d", requesttime, iTargetNPT));
13755
13756 uint32 startOfSeekWindow = 0;
13757 if (requesttime > iSyncPointSeekWindow)
13758 {
13759 startOfSeekWindow = (requesttime - iSyncPointSeekWindow);
13760 }
13761 uint32 endOfSeekWindow = requesttime + iSyncPointSeekWindow;
13762
13763 PVPPlaybackPosition curpos;
13764 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13765 GetPlaybackClockPosition(curpos);
13766 bool oSFR = false;
13767
13768 //depending on whether it is fwd or rwnd, the window is different
13769 //if doing a rwnd, the worst case window is (0, currentplaybackposition)
13770 //if doing a fwd, the worst case window is (currentplaybackposition, endofclip)
13771 if (requesttime <= curpos.iPosValue.millisec_value)
13772 {
13773 //requested pos <= currpos => rwnd
13774 //cap end of seek window to be the current play back pos
13775 endOfSeekWindow = curpos.iPosValue.millisec_value;
13776 }
13777 if (requesttime > curpos.iPosValue.millisec_value)
13778 {
13779 //requested pos > currpos => fwd
13780 //cap start of seek window to be the current play back pos
13781 startOfSeekWindow = curpos.iPosValue.millisec_value;
13782 }
13783
13784 // 1) Check if the Modified target position falls within the window
13785 if ((iTargetNPT >= startOfSeekWindow) &&
13786 (iTargetNPT <= endOfSeekWindow))
13787 {
13788 // Check for SFR
13789 // In case if actual playback position
13790 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
13791 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
13792 "RequestedNPT(%d) ModifiedTargetNPT(%d) is in the window (%d, %d), Seeking To %d",
13793 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, iTargetNPT));
13794
13795 requesttime = iTargetNPT;
13796 }
13797 else
13798 {
13799 // Check for SFR
13800 // SFR means currplaybackpos < requestedpos
13801 if (curpos.iPosValue.millisec_value < requesttime)
13802 {
13803 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
13804 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
13805 "CurrNPT(%d) less than RequestedNPT(%d) Ignoring ModifiedTargetNPT(%d) and the window (%d, %d), Doing SFR",
13806 curpos.iPosValue.millisec_value, requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
13807
13808 oSFR = true;
13809
13810 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13811 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoAttemptingSFRAsPartOfSetPlayBackRange, puuid, NULL));
13812 SendInformationalEvent(PVMFInfoPositionStatus, OSCL_STATIC_CAST(PVInterface*, infomsg));
13813 infomsg->removeRef();
13814
13815 }
13816 else
13817 {
13818 // if the actual seek point is before the window start,
13819 // or if the actual seek point is after the window end,
13820 // then go back to start of the seek window only in case of a finite window
13821 // in case of infinite window just go to the requested position and do normal
13822 // repositioning
13823 if (iSyncPointSeekWindow == 0x7FFFFFFF)
13824 {
13825 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
13826 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
13827 "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt True",
13828 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
13829
13830 iTargetNPT = requesttime;
13831 }
13832 else
13833 {
13834 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0,
13835 "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() - "
13836 "RequestedNPT(%d) ModifiedTargetNPT(%d) is outside the window (%d, %d), Seeking To %d Seek-To-SyncPt False",
13837 requesttime, iTargetNPT, startOfSeekWindow, endOfSeekWindow, startOfSeekWindow));
13838
13839 requesttime = startOfSeekWindow;
13840 iTargetNPT = requesttime;
13841 }
13842 }
13843 }
13844
13845 if (oSFR)
13846 {
13847 // No need to change source position so go to skipping at sink nodes
13848 // First determine to what time sink nodes should skip to
13849 // Get current playback clock position in media data time
13850 uint32 clockcurpos = 0;
13851 bool tmpbool = false;
13852 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
13853
13854 // for SFR since the source node is bypassed, there will be no frames generated with new
13855 // Stream ID so, for skip to complete on Sink Node, Stream ID needs to be decremented. As
13856 // there will be no new Stream in case of SFR.
13857 --iStreamID;
13858
13859 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13860 (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() New source reposition before current position so no need to change source position."));
13861
13862 if (iSkipToRequestedPosition)
13863 {
13864 // Skip to the requested begin position
13865 // Add the difference of target NPT with current time in NPT to the current clock to get media data time to skip to.
13866 iActualMediaDataTS = clockcurpos;
13867 iSkipMediaDataTS = (requesttime - curpos.iPosValue.millisec_value) + clockcurpos;
13868 iActualNPT = requesttime;
13869 iWatchDogTimerInterval = requesttime - curpos.iPosValue.millisec_value;
13870
13871 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13872 (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Skip-to-requested position SET. ActualNPT=%d, ActualMediaTS=%d, AdjustedMediaTS=%d",
13873 iActualNPT, iActualMediaDataTS, iSkipMediaDataTS));
13874 }
13875 else
13876 {
13877 // Just continue playback from current position
13878 iActualMediaDataTS = clockcurpos;
13879 iSkipMediaDataTS = clockcurpos;
13880 iActualNPT = curpos.iPosValue.millisec_value;
13881 iWatchDogTimerInterval = 0;
13882
13883 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
13884 (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Skip-to-requested position NOT SET so continue playing. ActualNPT=%d, ActualMediaTS=%d, AdjustedMediaTS=%d",
13885 iActualNPT, iActualMediaDataTS, iSkipMediaDataTS));
13886 }
13887
13888 PVMFStatus retval = DoSinkNodeSkipMediaDataDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext, true);
13889 if (retval != PVMFSuccess)
13890 {
13891 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Skipping media data request in sink nodes failed. Repositioning did not complete."));
13892 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13893 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSink, puuid, NULL));
13894
13895 //clear the pending direction change NPT.
13896 iChangeDirectionNPT.iIndeterminate = true;
13897
13898 // Complete the SetPlaybackRange() command as failed
13899 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval, OSCL_STATIC_CAST(PVInterface*, errmsg));
13900
13901 errmsg->removeRef();
13902 errmsg = NULL;
13903 }
13904
13905 }
13906 else
13907 {
13908 // Do the source positioning
13909 PVMFStatus retval = DoSourceNodeSetDataSourcePositionDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext);
13910 if (retval != PVMFSuccess)
13911 {
13912 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() SetDataSourcePosition failed. Playback position change has been cancelled"));
13913 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
13914 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, NULL));
13915
13916 // Complete the SetPlaybackRange() command as failed
13917 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval, OSCL_STATIC_CAST(PVInterface*, errmsg));
13918
13919 errmsg->removeRef();
13920 errmsg = NULL;
13921 }
13922 }
13923
13924 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeQueryDataSourcePositionDuringPlayback() Out"));
13925 }
13926
CalculateActualPlaybackPosition()13927 void PVPlayerEngine::CalculateActualPlaybackPosition()
13928 {
13929 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition In"));
13930
13931 PVPPlaybackPosition curpos;
13932 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
13933 GetPlaybackClockPosition(curpos);
13934
13935 // Following code has been taken from MP4 parser node, all the vars are kept very near to the MP4 parser node.
13936 // Previously the calculation of before and after sync point was done in MP4 parser node.
13937
13938 if (curpos.iPosValue.millisec_value > iTargetNPT)
13939 {
13940 // curpos.iPosValue.millisec_value was passed as iActualNPT in QueryDataSourcePosition
13941 // which became aActualNPT while collection, and used to decide forward and reverse repos.
13942 iBackwardReposFlag = true;
13943 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition In: Backward Reposition"));
13944 }
13945 else
13946 {
13947 iForwardReposFlag = true;
13948 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition In: Forward Reposition"));
13949 }
13950
13951 // pick the closest time to targetNPT
13952 uint32 delta = 0;
13953 uint32 diffBetSeekPointBeforeAndTarget = 0;
13954 if (PVTimeComparisonUtils::IsEarlier(iSeekPointBeforeTargetNPT, iTargetNPT, delta))
13955 {
13956 // this should always be true when checking the SeekPointBefore with
13957 // targetNPT.
13958 diffBetSeekPointBeforeAndTarget = delta;
13959 delta = 0;
13960 }
13961 else
13962 {
13963 // this will only happen when mp4ff library returns an SeekPointBefore which
13964 // is after targetNPT with small delta because of some rounding off error in
13965 // media clock converter class.
13966 diffBetSeekPointBeforeAndTarget = delta;
13967 delta = 0;
13968 }
13969
13970 uint32 diffBetSeekPointAfterAndTarget = 0;
13971 if (PVTimeComparisonUtils::IsEarlier(iTargetNPT, iSeekPointAfterTargetNPT, delta))
13972 {
13973 // this should always be true when checking the SeekPointAfter with
13974 // targetNPT.
13975 diffBetSeekPointAfterAndTarget = delta;
13976 delta = 0;
13977 }
13978 else
13979 {
13980 // this should never happen.
13981 diffBetSeekPointAfterAndTarget = delta;
13982 delta = 0;
13983 }
13984
13985 // modify the target NPT and set it to the closest I-frame returned by parser node.
13986 if (diffBetSeekPointAfterAndTarget < diffBetSeekPointBeforeAndTarget)
13987 {
13988 iTargetNPT = iSeekPointAfterTargetNPT;
13989 }
13990 else
13991 {
13992 if (iSeekPointBeforeTargetNPT < curpos.iPosValue.millisec_value && iForwardReposFlag)
13993 {
13994 iTargetNPT = iSeekPointAfterTargetNPT;
13995 iForwardReposFlag = false;
13996 }
13997 else
13998 {
13999 iTargetNPT = iSeekPointBeforeTargetNPT;
14000 iForwardReposFlag = false;
14001 }
14002 }
14003 if (iBackwardReposFlag) // To avoid backwardlooping :: A flag to remember backward repositioning
14004 {
14005 iTargetNPT = iSeekPointBeforeTargetNPT;
14006 iBackwardReposFlag = false;
14007 }
14008
14009
14010 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
14011 "PVPlayerEngine::CalculateActualPlaybackPosition()"
14012 "targetNPT %d Current NPT %d, Modified Target NPT %d, SeekPointBeforeTargetNPT %d, SeekPointAfterTargetNPT %d ",
14013 iCurrentBeginPosition.iPosValue.millisec_value, curpos.iPosValue.millisec_value, iTargetNPT, iSeekPointBeforeTargetNPT, iSeekPointAfterTargetNPT));
14014
14015 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::CalculateActualPlaybackPosition Out"));
14016 }
14017
HandleSourceNodeSetDataSourcePositionDuringPlayback(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14018 void PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14019 {
14020 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() In"));
14021
14022 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
14023 {
14024 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition failed. Playback position change has been cancelled"));
14025
14026 if (aNodeResp.GetCmdStatus() == PVMFErrNotSupported || aNodeResp.GetCmdStatus() == PVMFErrArgument)
14027 {
14028 PVPPlaybackPosition curpos;
14029 curpos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
14030 GetPlaybackClockPosition(curpos);
14031 uint32 clockcurpos = 0;
14032 bool tmpbool = false;
14033 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
14034
14035 // since repositioning is not supported continue playing from current position.
14036 iWatchDogTimerInterval = 0;
14037 iActualNPT = curpos.iPosValue.millisec_value;
14038 iActualMediaDataTS = clockcurpos;
14039 iSkipMediaDataTS = clockcurpos;
14040
14041 iStartNPT = iActualNPT;
14042 iStartMediaDataTS = iSkipMediaDataTS;
14043
14044 // also decrement the stream id as no skip will be called on MIO node.
14045 --iStreamID;
14046
14047 // For non-fatal error, continue playback by resuming the clock
14048 StartPlaybackClock();
14049 // Complete the SetPlaybackRange() command as notsupported / failed
14050 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, aNodeResp.GetCmdStatus());
14051 }
14052 else
14053 {
14054 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14055 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() failed, Add EH command"));
14056 bool ehPending = CheckForPendingErrorHandlingCmd();
14057 if (ehPending)
14058 {
14059 // there should be no error handling queued.
14060 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14061 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() Already EH pending, should never happen"));
14062 return;
14063 }
14064 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14065 if (aNodeResp.GetEventExtensionInterface())
14066 {
14067 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14068 }
14069
14070 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14071 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
14072 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
14073 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE, NULL, NULL, NULL, false);
14074 }
14075 return;
14076 }
14077
14078 if ((iCurrentBeginPosition.iMode != PVPPBPOS_MODE_END_OF_CURRENT_PLAY_ELEMENT) &&
14079 (iCurrentBeginPosition.iMode != PVPPBPOS_MODE_END_OF_CURRENT_PLAY_SESSION))
14080 {
14081 if (iCurrentBeginPosition.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
14082 {
14083 iActualMediaDataTS = iDataSourcePosParams.iActualMediaDataTS;
14084 iActualNPT = iDataSourcePosParams.iActualNPT;
14085 }
14086
14087 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
14088 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() SetDataSourcePosition() successful. StartMediaTS %d ms, ActualPBPos %d ms",
14089 iActualMediaDataTS, iActualNPT));
14090
14091 if (iCurrentBeginPosition.iPosUnit == PVPPBPOSUNIT_PLAYLIST)
14092 {
14093 if (iTargetNPT >= iActualNPT)
14094 {
14095 iWatchDogTimerInterval = iTargetNPT - iActualNPT;
14096 }
14097 }
14098 // Compute the difference between actualNPT and targetNPT before any adjustments
14099 else if (iTargetNPT >= iActualNPT)
14100 {
14101 iWatchDogTimerInterval = iTargetNPT - iActualNPT;
14102 }
14103
14104 //iCurrentBeginPosition.iPosUnit has served its purpose, it is ok if it is overwritten
14105 if (iSkipToRequestedPosition && (iActualNPT < iTargetNPT))
14106 {
14107 if (iTargetNPT - iActualNPT >= iNodeDataQueuingTimeout)
14108 {
14109 // Can't adjust the skip time back so use the returned values to skip to
14110 iSkipMediaDataTS = iActualMediaDataTS;
14111 iTargetNPT = iActualNPT;
14112 iWatchDogTimerInterval = 0;
14113 }
14114 else
14115 {
14116 //check if source node wants to override
14117 uint32 startNPTFrmSource = iActualNPT;
14118 if (iSourceNodePBCtrlIF->ComputeSkipTimeStamp(iTargetNPT,
14119 iActualNPT,
14120 iActualMediaDataTS,
14121 iSkipMediaDataTS,
14122 startNPTFrmSource) == PVMFSuccess)
14123 {
14124 iWatchDogTimerInterval = startNPTFrmSource - iActualNPT;
14125 iActualNPT = startNPTFrmSource;
14126 }
14127 else
14128 {
14129 // Adjust the media data time to skip-to to correspond to the requested time
14130 // Add the difference of target NPT with actual playback position in NPT to the actual media data time to get time to skip to.
14131 iSkipMediaDataTS = iActualMediaDataTS + (iTargetNPT - iActualNPT);
14132 // Set the actual playback position to the requested time since actual media data TS was adjusted
14133 // This is important since the difference between the two is used to calculate the NPT to media data offset in HandleSinkNodeskipMediaDataDuringPlayback()
14134 iActualNPT = iTargetNPT;
14135 }
14136
14137 }
14138 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
14139 }
14140 else
14141 {
14142 // Can't adjust the skip time back so just use the returned values to skip to
14143 iSkipMediaDataTS = iActualMediaDataTS;
14144 iTargetNPT = iActualNPT;
14145 iCurrentBeginPosition.iPosValue.millisec_value = iActualNPT;
14146 iCurrentBeginPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
14147 iWatchDogTimerInterval = 0;
14148 }
14149
14150 uint32 clockcurpos = 0;
14151 bool tmpbool;
14152 // Get current playback clock position
14153 iPlaybackClock.GetCurrentTime32(clockcurpos, tmpbool, PVMF_MEDIA_CLOCK_MSEC);
14154
14155 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
14156 (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() After adjustment StartMediaTS %d ms, AdjustedMediaTS %d ms, ActualPBPos %d ms Clock %d ms",
14157 iActualMediaDataTS, iSkipMediaDataTS, iActualNPT, clockcurpos));
14158
14159 // Repositioning so reset the EOS flag for each active datapath
14160 for (uint32 i = 0; i < iDatapathList.size(); ++i)
14161 {
14162 if (iDatapathList[i].iDatapath)
14163 {
14164 iDatapathList[i].iEndOfDataReceived = false;
14165 }
14166 }
14167
14168 PVMFStatus retval = DoSinkNodeSkipMediaDataDuringPlayback(aNodeContext.iCmdId, aNodeContext.iCmdContext);
14169 if (retval != PVMFSuccess)
14170 {
14171 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() Skipping media data request in sink nodes failed. Repositioning did not complete."));
14172
14173 // clear the pending direction change NPT.
14174 iChangeDirectionNPT.iIndeterminate = true;
14175
14176 // Complete the SetPlaybackRange() command as failed
14177 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, retval);
14178 }
14179 }
14180 else
14181 {
14182 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14183 if (aNodeResp.GetEventExtensionInterface() != NULL)
14184 {
14185 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14186 }
14187 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14188 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
14189
14190 // Complete the SetPlaybackRange() command as Success
14191 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, aNodeResp.GetCmdStatus(), OSCL_STATIC_CAST(PVInterface*, errmsg));
14192 if (errmsg)
14193 {
14194 errmsg->removeRef();
14195 errmsg = NULL;
14196 }
14197 }
14198 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeSetDataSourcePositionDuringPlayback() Out"));
14199 }
14200
HandleSinkNodeSkipMediaDataDuringPlayback(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14201 void PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14202 {
14203 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
14204 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() for %s Tick=%d",
14205 aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
14206
14207 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
14208 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() for %s, iNumPVMFInfoStartOfDataPending=%d",
14209 aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), iNumPVMFInfoStartOfDataPending));
14210
14211 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
14212 {
14213 // Sink node report error with SkipMediaData()
14214 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Sink node report error for SkipMediaData(). Asserting"));
14215 OSCL_ASSERT(false);
14216 }
14217
14218 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
14219
14220 // Stop the sink that has reached the skipping end point until other sinks are ready
14221 if (aNodeContext.iEngineDatapath->iDatapath && aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF)
14222 {
14223 aNodeContext.iEngineDatapath->iSinkNodeSyncCtrlIF->ClockStopped();
14224 }
14225 else
14226 {
14227 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Datapath does not exist or sync control IF not available."));
14228 }
14229
14230 --iNumPendingSkipCompleteEvent;
14231
14232 --iNumPendingNodeCmd;
14233
14234 if (iNumPendingNodeCmd == 0)
14235 {
14236 // Set the clock to the specified begin time just before Start of playback Clock
14237 iPlaybackClock.Stop();
14238 bool overflow = 0;
14239 iPlaybackClock.SetStartTime32(iSkipMediaDataTS, PVMF_MEDIA_CLOCK_MSEC, overflow);
14240
14241 if (iOverflowFlag)
14242 {
14243 iOverflowFlag = false;
14244 iActualNPT = iSkipMediaDataTS;
14245 }
14246 if ((iNumPVMFInfoStartOfDataPending == 0) &&
14247 (iState == PVP_ENGINE_STATE_STARTED))
14248 {
14249 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
14250 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Skipping WatchDogTimer - Starting PlayBackClock"));
14251 StartPlaybackClock();
14252 }
14253 else
14254 {
14255 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
14256 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Setting WatchDogTimer for %d ms, TargetNPT=%d ActualNPT=%d, if interval zero set to default 1 second",
14257 iWatchDogTimerInterval, iTargetNPT, iActualNPT));
14258 // There can be a case in which WatchDogTimerInterval is zero and iNumPVMFInfoStartOfDataPending is greater than zero.
14259 // In this case it is possible InfoStartofData is not sent by Sink Nodes for some time and player hangs. To avoid the player hang
14260 // set the watchdog timer Interval to the default value of 1 second. If interval is 0, it will be set to default 1 second.
14261 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
14262 iWatchDogTimer->Start();
14263 }
14264
14265 // Set the actual playback position to the requested time since actual media data TS was adjusted
14266 // This is important since the difference between the two is used to calculate the NPT to media data offset
14267 // This is not required here as the ActualPlaybackPosition is already adjusted before calling Skip on Sink Node.
14268 // iActualNPT=iCurrentBeginPosition.iPosValue.millisec_value;
14269
14270 //clear the pending direction change NPT.
14271 iChangeDirectionNPT.iIndeterminate = true;
14272 // Save the start NPT and TS
14273 iStartNPT = iActualNPT;
14274 iStartMediaDataTS = iSkipMediaDataTS;
14275 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO,
14276 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() TargetNPT %d, ActualNPT %d StartTS %d",
14277 iTargetNPT, iStartNPT, iStartMediaDataTS));
14278 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
14279 (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() TargetNPT %d, ActualNPT %d StartTS %d",
14280 iTargetNPT, iStartNPT, iStartMediaDataTS));
14281
14282 // Send event to the observer indicating start of data
14283 if (iDataSourcePosParams.iMode == PVMF_SET_DATA_SOURCE_POSITION_MODE_NOW)
14284 {
14285 /* Reset */
14286 iDataSourcePosParams.iActualMediaDataTS = 0;
14287 iDataSourcePosParams.iActualNPT = 0;
14288 iDataSourcePosParams.iMode = PVMF_SET_DATA_SOURCE_POSITION_MODE_UNKNOWN;
14289 iDataSourcePosParams.iPlayElementIndex = -1;
14290 iDataSourcePosParams.iSeekToSyncPoint = true;
14291 iDataSourcePosParams.iTargetNPT = 0;
14292 SendInformationalEvent(PVMFInfoStartOfData);
14293 }
14294
14295 // send the actual playback position from where playback will resume after reposition.
14296 PVPPlaybackPosition actualPlaybackPosition;
14297 actualPlaybackPosition.iPosValue.millisec_value = iStartNPT;
14298 actualPlaybackPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
14299
14300 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14301 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackFromBeginTime, puuid, NULL));
14302 SendInformationalEvent(PVMFInfoActualPlaybackPosition, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&actualPlaybackPosition);
14303 infomsg->removeRef();
14304
14305 // Complete the SetPlaybackRange() or SetPlaybackRate()
14306 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
14307 }
14308
14309 if ((iNumPendingSkipCompleteEvent == 0) && (iNumPVMFInfoStartOfDataPending == 0))
14310 {
14311 if (iWatchDogTimer->IsBusy())
14312 {
14313 iWatchDogTimer->Cancel();
14314 }
14315 // we have received all the bos event for
14316 // playback hasnt started yet
14317
14318 StartPlaybackClock();
14319 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback - PlayClock Started"));
14320 }
14321
14322 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeSkipMediaDataDuringPlayback() Out"));
14323 }
14324
14325
HandleSourceNodePause(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14326 void PVPlayerEngine::HandleSourceNodePause(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14327 {
14328 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePause() In"));
14329
14330 switch (aNodeResp.GetCmdStatus())
14331 {
14332 case PVMFSuccess:
14333 {
14334 // Pause command is complete
14335 SetEngineState(PVP_ENGINE_STATE_PAUSED);
14336 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
14337 }
14338 break;
14339
14340 default:
14341 {
14342 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14343 (0, "PVPlayerEngine::HandleSourceNodePause() failed, Add EH command"));
14344 bool ehPending = CheckForPendingErrorHandlingCmd();
14345 if (ehPending)
14346 {
14347 // there should be no error handling queued.
14348 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodePause() Already EH pending, should never happen"));
14349 return;
14350 }
14351 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14352 if (aNodeResp.GetEventExtensionInterface())
14353 {
14354 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14355 }
14356
14357 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14358 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
14359 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
14360
14361 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
14362 }
14363 break;
14364 }
14365
14366 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodePause() Out"));
14367 }
14368
14369
HandleSourceNodeResume(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14370 void PVPlayerEngine::HandleSourceNodeResume(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14371 {
14372 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeResume() In"));
14373
14374 PVMFStatus cmdstatus = PVMFErrNotSupported;
14375
14376 switch (aNodeResp.GetCmdStatus())
14377 {
14378 case PVMFSuccess:
14379 {
14380 // Issue Skip on Sink Node and Start on datapaths back to back. This is done to make sure that
14381 // sink node is started only after discarding the data from an earlier stream.
14382 if (iChangePlaybackPositionWhenResuming || iChangePlaybackDirectionWhenResuming)
14383 {
14384 PVMFStatus cmdstatus = DoSinkNodeSkipMediaData(aNodeContext.iCmdId, aNodeContext.iCmdContext);
14385 if (cmdstatus != PVMFSuccess)
14386 {
14387 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Skip of sink node did a leave, asserting"));
14388 OSCL_ASSERT(false);
14389 }
14390 }
14391 // Issue start to all active datapaths
14392 iNumPendingDatapathCmd = 0;
14393 for (uint32 i = 0; i < iDatapathList.size(); ++i)
14394 {
14395 if (iDatapathList[i].iDatapath)
14396 {
14397 PVMFStatus retval = DoDatapathStart(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
14398 if (retval == PVMFSuccess)
14399 {
14400 ++iNumPendingDatapathCmd;
14401 cmdstatus = PVMFSuccess;
14402 }
14403 else
14404 {
14405 cmdstatus = retval;
14406 break;
14407 }
14408 }
14409 }
14410
14411 if (iNumPendingDatapathCmd == 0)
14412 {
14413 bool ehPending = CheckForPendingErrorHandlingCmd();
14414 if (ehPending)
14415 {
14416 // there should be no error handling queued.
14417 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Already EH pending, should never happen"));
14418 return;
14419 }
14420 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Report command as failed, Add EH command"));
14421 iCommandCompleteStatusInErrorHandling = cmdstatus;
14422 iCommandCompleteErrMsgInErrorHandling = NULL;
14423 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
14424 }
14425 }
14426 break;
14427
14428 default:
14429 {
14430 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() failed, Add EH command"));
14431 bool ehPending = CheckForPendingErrorHandlingCmd();
14432 if (ehPending)
14433 {
14434 // there should be no error handling queued.
14435 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeResume() Already EH pending, should never happen"));
14436 return;
14437 }
14438 cmdstatus = aNodeResp.GetCmdStatus();
14439 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14440 if (aNodeResp.GetEventExtensionInterface())
14441 {
14442 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14443 }
14444
14445 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14446 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
14447 iCommandCompleteStatusInErrorHandling = cmdstatus;
14448
14449 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
14450 }
14451 break;
14452 }
14453
14454 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeResume() Out"));
14455 }
14456
14457
HandleSourceNodeStop(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14458 void PVPlayerEngine::HandleSourceNodeStop(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14459 {
14460 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStop() In"));
14461
14462 PVMFStatus cmdstatus = PVMFFailure;
14463
14464 switch (aNodeResp.GetCmdStatus())
14465 {
14466 case PVMFSuccess:
14467 {
14468 // Issue teardown sequence to all active datapaths
14469 iNumPendingDatapathCmd = 0;
14470 for (uint32 i = 0; i < iDatapathList.size(); ++i)
14471 {
14472 if (iDatapathList[i].iDatapath)
14473 {
14474 PVMFStatus retval = DoDatapathTeardown(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
14475 if (retval == PVMFSuccess)
14476 {
14477 ++iNumPendingDatapathCmd;
14478 cmdstatus = PVMFSuccess;
14479 }
14480 else
14481 {
14482 cmdstatus = retval;
14483 break;
14484 }
14485 }
14486 }
14487 }
14488
14489 if (iNumPendingDatapathCmd == 0)
14490 {
14491 bool ehPending = CheckForPendingErrorHandlingCmd();
14492 if (ehPending)
14493 {
14494 // there should be no error handling queued.
14495 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStop() Already EH pending, should never happen"));
14496 return;
14497 }
14498 // No active datapath to shutdown - not possible in stop
14499 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStop() Datapath Teardown failed, Add EH command"));
14500 iCommandCompleteErrMsgInErrorHandling = NULL;
14501 iCommandCompleteStatusInErrorHandling = cmdstatus;
14502 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
14503 }
14504 break;
14505
14506 default:
14507 {
14508 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14509 (0, "PVPlayerEngine::HandleSourceNodeStop() Source node stop failed, go in error handling, Add EH command"));
14510 bool ehPending = CheckForPendingErrorHandlingCmd();
14511 if (ehPending)
14512 {
14513 // there should be no error handling queued.
14514 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeStop() Already EH pending, should never happen"));
14515 return;
14516 }
14517 cmdstatus = aNodeResp.GetCmdStatus();
14518 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14519 if (aNodeResp.GetEventExtensionInterface())
14520 {
14521 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14522 }
14523
14524 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14525 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
14526 iCommandCompleteStatusInErrorHandling = cmdstatus;
14527
14528 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
14529 }
14530 break;
14531 }
14532
14533 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeStop() Out"));
14534 }
14535
14536
HandleSourceNodeReset(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14537 void PVPlayerEngine::HandleSourceNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14538 {
14539 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeReset() In"));
14540
14541 PVMFStatus cmdstatus = PVMFErrNotSupported;
14542
14543 if (aNodeResp.GetCmdStatus() == PVMFSuccess)
14544 {
14545 if (iSourceNode->GetState() != EPVMFNodeIdle)
14546 {
14547 // when reset completes on Source node, source node should be in Idle State,
14548 // If not then just assert.
14549 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14550 (0, "PVPlayerEngine::HandleSourceNodeReset() Source Node not in a idle state after reset, Asserting"));
14551 OSCL_ASSERT(false);
14552 }
14553
14554 PVMFStatus status = PVMFFailure;
14555 status = iSourceNode->ThreadLogoff();
14556 if (status != PVMFSuccess)
14557 {
14558 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoEngineDatapathTeardown() Threadlogoff on SourceNode Failed"));
14559 OSCL_ASSERT(false);
14560 }
14561
14562 if (iSourceNode->GetState() != EPVMFNodeCreated)
14563 {
14564 // when reset completes on Source node, source node should be in Idle State,
14565 // If not then just assert.
14566 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14567 (0, "PVPlayerEngine::HandleSourceNodeReset() Source Node not in a created state after threadlogoff, Asserting"));
14568 OSCL_ASSERT(false);
14569 }
14570
14571 // Reset active datapaths
14572 if (!iDatapathList.empty())
14573 {
14574 iNumPendingDatapathCmd = 0;
14575 PVMFCommandId cmdid = -1;
14576 int32 leavecode = 0;
14577 for (uint32 i = 0; i < iDatapathList.size(); ++i)
14578 {
14579 if ((iDatapathList[i].iDatapath != NULL) &&
14580 (iDatapathList[i].iTrackInfo != NULL) &&
14581 (iDatapathList[i].iDatapath->iState != PVPDP_IDLE))
14582 {
14583 PVMFStatus retval = DoDatapathReset(iDatapathList[i], aNodeContext.iCmdId, aNodeContext.iCmdContext);
14584 if (retval == PVMFSuccess)
14585 {
14586 ++iNumPendingDatapathCmd;
14587 cmdstatus = PVMFSuccess;
14588 }
14589 else
14590 {
14591 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14592 (0, "PVPlayerEngine::HandleSourceNodeReset() Reset failed, Asserting"));
14593 OSCL_ASSERT(false);
14594 break;
14595 }
14596 }
14597 else if (iDatapathList[i].iDecNode != NULL)
14598 {
14599 // This happens in case of error during prepare, when datapaths have not yet
14600 // been fully constructed.
14601 // reset the decoder node during inteligent track selection
14602 // Call Reset() on the decoder node
14603 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iDecNode, NULL, aNodeContext.iCmdId, aNodeContext.iCmdContext, PVP_CMD_DecNodeReset);
14604
14605 leavecode = IssueDecNodeReset(iDatapathList[i].iDecNode, iDatapathList[i].iDecNodeSessionId, (OsclAny*) context, cmdid);
14606
14607 if (cmdid != -1 && leavecode == 0)
14608 {
14609 ++iNumPendingDatapathCmd;
14610 }
14611 else
14612 {
14613 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeReset() Reset on dec node leaved, asserting"));
14614 FreeEngineContext(context);
14615 OSCL_ASSERT(false);
14616 }
14617 }
14618 else if (iDatapathList[i].iSinkNode != NULL)
14619 {
14620 // This happens in case of error during prepare, when datapaths have not yet
14621 // been fully constructed.
14622 // reset the sink node during inteligent track selection
14623 // Call Reset() on the sink node
14624 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aNodeContext.iCmdId, aNodeContext.iCmdContext, PVP_CMD_SinkNodeReset);
14625
14626 leavecode = IssueSinkNodeReset(&(iDatapathList[i]), (OsclAny*) context, cmdid);
14627
14628 if (cmdid != -1 && leavecode == 0)
14629 {
14630 ++iNumPendingDatapathCmd;
14631 }
14632 else
14633 {
14634 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeReset() Reset on sink node leaved, asserting"));
14635 FreeEngineContext(context);
14636 OSCL_ASSERT(false);
14637 }
14638 }
14639 else
14640 {
14641 // No Sink nodes and no datapaths created yet so just do Enginedatapath Teardown.
14642 DoEngineDatapathTeardown(iDatapathList[i]);
14643 }
14644 }
14645
14646 if (iNumPendingDatapathCmd == 0)
14647 {
14648 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14649 (0, "PVPlayerEngine::HandleSourceNodeReset() Reset on SourceNode completed and no datapath or sink node to reset."));
14650 // Reset on source node is complete and there are no datapaths or sink nodes to reset,
14651 // now need to remove the data sinks and sources
14652 // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
14653 SetEngineState(PVP_ENGINE_STATE_IDLE);
14654 RunIfNotReady();
14655 }
14656 }
14657 else
14658 {
14659 // Reset on source node is complete and there are no datapaths or sink nodes to reset,
14660 // now need to remove the data sinks and sources
14661 // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
14662 SetEngineState(PVP_ENGINE_STATE_IDLE);
14663 RunIfNotReady();
14664 }
14665 }
14666 else
14667 {
14668 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14669 (0, "PVPlayerEngine::HandleSourceNodeReset() Reset failed on Source Node, Asserting"));
14670 OSCL_ASSERT(false);
14671 }
14672
14673 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeReset() Out"));
14674 }
14675
14676
HandleSinkNodePause(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14677 void PVPlayerEngine::HandleSinkNodePause(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14678 {
14679 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodePause() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
14680
14681 // Decrement the counter for pending cmds
14682 --iNumPendingDatapathCmd;
14683
14684 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
14685 {
14686 bool ehPending = CheckForPendingErrorHandlingCmd();
14687 if (ehPending)
14688 {
14689 // there should be no error handling queued.
14690 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodePause() Already EH pending, should never happen"));
14691 return;
14692 }
14693 else
14694 {
14695 // Cancel any pending node/datapath commands
14696 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodePause() Failed, Add EH command"));
14697 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14698 if (aNodeResp.GetEventExtensionInterface())
14699 {
14700 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14701 }
14702
14703 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14704 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkFatal, puuid, nextmsg));
14705 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
14706 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
14707 }
14708
14709 return;
14710 }
14711
14712 if (iNumPendingDatapathCmd == 0)
14713 {
14714 // Auto-pause is complete
14715 SetEngineState(PVP_ENGINE_STATE_AUTO_PAUSED);
14716 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodePause() Report command as success"));
14717 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
14718 }
14719
14720 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodePause() Out"));
14721 }
14722
14723
HandleSinkNodeResume(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14724 void PVPlayerEngine::HandleSinkNodeResume(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14725 {
14726 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeResume() In %s", aNodeContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
14727
14728 // Decrement the counter for pending cmds
14729 --iNumPendingDatapathCmd;
14730
14731 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
14732 {
14733 bool ehPending = CheckForPendingErrorHandlingCmd();
14734 if (ehPending)
14735 {
14736 // there should be no error handling queued.
14737 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeResume() Already EH pending, should never happen"));
14738 return;
14739 }
14740 else
14741 {
14742 // Cancel any pending node/datapath commands
14743 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeResume() Failed, Add EH command"));
14744 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14745 if (aNodeResp.GetEventExtensionInterface())
14746 {
14747 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
14748 }
14749
14750 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14751 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkFatal, puuid, nextmsg));
14752 iCommandCompleteStatusInErrorHandling = aNodeResp.GetCmdStatus();
14753 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME, NULL, NULL, NULL, false);
14754 }
14755 return;
14756 }
14757
14758 if (iNumPendingDatapathCmd == 0)
14759 {
14760 // Auto-resume is complete
14761 // Resume the playback clock only if InfoStartofData has been received for all tracks.
14762 // If SetPlaybackRange is called in Auto-Pause state, its possible that engine is waiting for InfoStartofData.
14763 // If waiting, restart the watchdog timer which was cancelled in Auto-Pause command.
14764 // this should only be done when engine is waiting for StartofData info event
14765 // after reposition. If already busy after SetPlaybackRange command complete,
14766 // then cancel it and start again. Playback clock will be started in either HandleSinkNodeInfoEvent or
14767 // PVPlayerWatchdogTimerEvent
14768 if (iNumPVMFInfoStartOfDataPending > 0)
14769 {
14770 if (iWatchDogTimerInterval > 0)
14771 {
14772 if (iWatchDogTimer->IsBusy())
14773 {
14774 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
14775 (0, "PVPlayerEngine::HandleSinkNodeResume - Pause after setplayback, Cancelling Watchdog timer, iNumPVMFInfoStartOfDataPending=%d", iNumPVMFInfoStartOfDataPending));
14776 iWatchDogTimer->Cancel();
14777 }
14778
14779 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
14780 (0, "PVPlayerEngine::HandleSinkNodeResume Setting WatchDogTimer for %d ms, iNumPVMFInfoStartOfDataPending=%d",
14781 iWatchDogTimerInterval, iNumPVMFInfoStartOfDataPending));
14782 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
14783 iWatchDogTimer->Start();
14784 }
14785 }
14786 // Auto-resume is complete & not waiting on PVMFInfoStartOfData, so go ahead and
14787 // start the clock
14788 if (iNumPVMFInfoStartOfDataPending == 0)
14789 {
14790 StartPlaybackClock();
14791
14792 // Notify data sinks that clock has started
14793 for (uint32 i = 0; i < iDatapathList.size(); ++i)
14794 {
14795 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
14796 {
14797 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
14798 }
14799 }
14800 }
14801
14802 SetEngineState(PVP_ENGINE_STATE_STARTED);
14803 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeResume() Report command as success"));
14804 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
14805 }
14806
14807 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeResume() Out"));
14808 }
14809
HandleSinkNodeReset(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14810 void PVPlayerEngine::HandleSinkNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14811 {
14812 OSCL_ASSERT(aNodeContext.iEngineDatapath != NULL);
14813 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeReset() In"));
14814
14815 // Decrement the counter for pending cmds
14816 --iNumPendingDatapathCmd;
14817
14818 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
14819 {
14820 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14821 (0, "PVPlayerEngine::HandleSinkNodeReset() Reset failed, assert"));
14822 OSCL_ASSERT(false);
14823 return;
14824 }
14825 else
14826 {
14827 // Reset for this sink node is complete
14828 //a sync call in engine - no async cmds issued here
14829 DoEngineDatapathTeardown(*(aNodeContext.iEngineDatapath));
14830 }
14831
14832 if (iNumPendingDatapathCmd == 0)
14833 {
14834 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14835 (0, "PVPlayerEngine::HandleSinkNodeReset() Reset on SourceNode and Sink nodes completed"));
14836 // Reset on source node and sink node is complete, now need to remove the data sinks and sources
14837 // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
14838 SetEngineState(PVP_ENGINE_STATE_IDLE);
14839 RunIfNotReady();
14840 }
14841
14842 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeReset() Out"));
14843 }
14844
HandleDecNodeReset(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)14845 void PVPlayerEngine::HandleDecNodeReset(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
14846 {
14847 OSCL_ASSERT(aNodeContext.iEngineDatapath != NULL);
14848 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeReset() In"));
14849
14850 // Decrement the counter for pending cmds
14851 --iNumPendingDatapathCmd;
14852
14853 if (aNodeResp.GetCmdStatus() != PVMFSuccess)
14854 {
14855 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14856 (0, "PVPlayerEngine::HandleDecNodeReset() Reset failed, assert"));
14857 OSCL_ASSERT(false);
14858 return;
14859 }
14860
14861 if (iNumPendingDatapathCmd == 0)
14862 {
14863 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14864 (0, "PVPlayerEngine::HandleDecNodeReset() Reset on SourceNode and dec nodes completed, now reset Sink nodes"));
14865 // Reset on source node and dec node is complete, now need to reset the sink nodes
14866 if (!iDatapathList.empty())
14867 {
14868 iNumPendingDatapathCmd = 0;
14869 PVMFCommandId cmdid = -1;
14870 int32 leavecode = 0;
14871 for (uint32 i = 0; i < iDatapathList.size(); ++i)
14872 {
14873 if (iDatapathList[i].iSinkNode != NULL)
14874 {
14875 // This happens in case of error during prepare, when datapaths have not yet
14876 // been fully constructed.
14877 // reset the sink node during inteligent track selection
14878 // Call Reset() on the sink node
14879 PVPlayerEngineContext* context = AllocateEngineContext(&(iDatapathList[i]), iDatapathList[i].iSinkNode, NULL, aNodeContext.iCmdId, aNodeContext.iCmdContext, PVP_CMD_SinkNodeReset);
14880
14881 leavecode = IssueSinkNodeReset(&(iDatapathList[i]), (OsclAny*) context, cmdid);
14882
14883 if (cmdid != -1 && leavecode == 0)
14884 {
14885 ++iNumPendingDatapathCmd;
14886 }
14887 else
14888 {
14889 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeReset() Reset on sink node leaved, asserting"));
14890 FreeEngineContext(context);
14891 OSCL_ASSERT(false);
14892 }
14893 }
14894 }
14895 }
14896 }
14897
14898 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeReset() Out"));
14899 }
14900
HandleDatapathPrepare(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)14901 void PVPlayerEngine::HandleDatapathPrepare(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
14902 {
14903 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
14904 (0, "PVPlayerEngine::HandleDatapathPrepare() for %s Tick=%d",
14905 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
14906
14907 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPrepare() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
14908
14909 // Decrement the counter for pending datapath cmds
14910 --iNumPendingDatapathCmd;
14911
14912 if (aDatapathStatus != PVMFSuccess)
14913 {
14914 bool ehPending = CheckForPendingErrorHandlingCmd();
14915 if (ehPending)
14916 {
14917 // there should be no error handling queued.
14918 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPrepare() Already EH pending, should never happen"));
14919 return;
14920 }
14921 else
14922 {
14923 // Cancel any pending node/datapath commands
14924 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
14925 (0, "PVPlayerEngine::HandleDatapathPrepare() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
14926 PVMFErrorInfoMessageInterface* nextmsg = NULL;
14927 if (aCmdResp)
14928 {
14929 if (aCmdResp->GetEventExtensionInterface())
14930 {
14931 nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
14932 }
14933 }
14934
14935 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
14936 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
14937 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
14938 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
14939 }
14940 return;
14941 }
14942
14943 if (iNumPendingDatapathCmd == 0)
14944 {
14945 // Reposition and/or start the source node
14946 PVMFStatus cmdstatus = DoSourceNodeQueryDataSourcePosition(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
14947 if (cmdstatus != PVMFSuccess)
14948 {
14949 // Setting position not supported so start the source node
14950 cmdstatus = DoSourceNodeStart(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
14951 }
14952
14953 if (cmdstatus != PVMFSuccess)
14954 {
14955 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPrepare() Report command as failed, Add EH command"));
14956 bool ehPending = CheckForPendingErrorHandlingCmd();
14957 if (ehPending)
14958 {
14959 // there should be no error handling queued.
14960 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPrepare() Already EH pending, should never happen"));
14961 return;
14962 }
14963 else
14964 {
14965 iCommandCompleteStatusInErrorHandling = cmdstatus;
14966 iCommandCompleteErrMsgInErrorHandling = NULL;
14967 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
14968 }
14969 }
14970 }
14971
14972 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPrepare() Out"));
14973 }
14974
14975
HandleDatapathStart(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)14976 void PVPlayerEngine::HandleDatapathStart(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
14977 {
14978 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
14979 (0, "PVPlayerEngine::HandleDatapathStart() for %s Tick=%d",
14980 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
14981
14982 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStart() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
14983
14984 // Decrement the counter for pending datapath cmds
14985 --iNumPendingDatapathCmd;
14986
14987 if (aDatapathStatus != PVMFSuccess)
14988 {
14989 bool ehPending = CheckForPendingErrorHandlingCmd();
14990 if (ehPending)
14991 {
14992 // there should be no error handling queued.
14993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStart() Already EH pending, should never happen"));
14994 return;
14995 }
14996 else
14997 {
14998 // Cancel any pending node/datapath commands
14999 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15000 (0, "PVPlayerEngine::HandleDatapathStart() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15001 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15002 if (aCmdResp)
15003 {
15004 if (aCmdResp->GetEventExtensionInterface())
15005 {
15006 nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
15007 }
15008 }
15009
15010 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15011 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
15012 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
15013 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE, NULL, NULL, NULL, false);
15014 }
15015 return;
15016 }
15017
15018 if (iNumPendingDatapathCmd == 0)
15019 {
15020 // This should never be happen if Skip on sink node has not completed (i.e. iNumPendingSkipCompleteEvent
15021 // is greater than zero). If this happens with iNumPendingSkipCompleteEvent > 0 then just assert.
15022 // Set the clock to the specified begin time just before Start of playback Clock
15023 iPlaybackClock.Stop();
15024 bool overflow = 0;
15025 iPlaybackClock.SetStartTime32(iSkipMediaDataTS, PVMF_MEDIA_CLOCK_MSEC, overflow);
15026
15027 if (!(iWatchDogTimer->IsBusy()))
15028 {
15029 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
15030 (0, "PVPlayerEngine::HandleDatapathStart() Setting WatchDogTimer for %d ms, TargetNPT=%d ActualNPT=%d, if interval zero set to default 1 second",
15031 iWatchDogTimerInterval, iTargetNPT, iActualNPT));
15032 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
15033 iWatchDogTimer->Start();
15034 }
15035 // Set the actual playback position to the requested time since actual media data TS was adjusted
15036 // This is important since the difference between the two is used to calculate the NPT to media data offset
15037 // This is not required here as the ActualPlaybackPosition is already adjusted before calling Skip on Sink Node.
15038 // iActualNPT=iCurrentBeginPosition.iPosValue.millisec_value;
15039
15040 // Save the start NPT and TS
15041 iStartNPT = iActualNPT;
15042 iStartMediaDataTS = iSkipMediaDataTS;
15043 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO,
15044 (0, "PVPlayerEngine::HandleDatapathStart() TargetNPT %d, StartNPT %d StartTS %d",
15045 iTargetNPT, iStartNPT, iStartMediaDataTS));
15046 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
15047 (0, "PVPlayerEngine::HandleDatapathStart() TargetNPT %d, StartNPT %d StartTS %d",
15048 iTargetNPT, iStartNPT, iStartMediaDataTS));
15049
15050 SetEngineState(PVP_ENGINE_STATE_PREPARED);
15051
15052 // send the actual playback position from where playback will resume after reposition.
15053 PVPPlaybackPosition actualPlaybackPosition;
15054 actualPlaybackPosition.iPosValue.millisec_value = iStartNPT;
15055 actualPlaybackPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
15056
15057 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15058 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackFromBeginTime, puuid, NULL));
15059 SendInformationalEvent(PVMFInfoActualPlaybackPosition, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&actualPlaybackPosition);
15060 infomsg->removeRef();
15061
15062 EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, PVMFSuccess);
15063 }
15064
15065 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStart() Out"));
15066 }
15067
15068
HandleDatapathPause(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)15069 void PVPlayerEngine::HandleDatapathPause(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
15070 {
15071 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
15072 (0, "PVPlayerEngine::HandleDatapathPause() for %s Tick=%d",
15073 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
15074
15075 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPause() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15076
15077 // Decrement the counter for pending datapath cmds
15078 --iNumPendingDatapathCmd;
15079
15080 if (aDatapathStatus != PVMFSuccess)
15081 {
15082 bool ehPending = CheckForPendingErrorHandlingCmd();
15083 if (ehPending)
15084 {
15085 // there should be no error handling queued.
15086 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPause() Already EH pending, should never happen"));
15087 return;
15088 }
15089 else
15090 {
15091 // Cancel any pending node/datapath commands
15092 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15093 (0, "PVPlayerEngine::HandleDatapathPause() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15094 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15095 if (aCmdResp)
15096 {
15097 if (aCmdResp->GetEventExtensionInterface())
15098 {
15099 nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
15100 }
15101 }
15102
15103 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15104 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
15105 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
15106 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
15107 }
15108 return;
15109 }
15110
15111 if (iNumPendingDatapathCmd == 0)
15112 {
15113 // Continue on by pauseing the source node
15114 PVMFStatus cmdstatus = DoSourceNodePause(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
15115
15116 if (cmdstatus != PVMFSuccess)
15117 {
15118 bool ehPending = CheckForPendingErrorHandlingCmd();
15119 if (ehPending)
15120 {
15121 // there should be no error handling queued.
15122 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPause() Already EH pending, should never happen"));
15123 return;
15124 }
15125 else
15126 {
15127 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathPause() Report command as failed, Add EH command"));
15128 iCommandCompleteStatusInErrorHandling = cmdstatus;
15129 iCommandCompleteErrMsgInErrorHandling = NULL;
15130 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE, NULL, NULL, NULL, false);
15131 }
15132 }
15133 }
15134
15135 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathPause() Out"));
15136 }
15137
15138
HandleDatapathResume(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)15139 void PVPlayerEngine::HandleDatapathResume(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
15140 {
15141 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
15142 (0, "PVPlayerEngine::HandleDatapathResume() for %s Tick=%d",
15143 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
15144
15145 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathResume() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15146
15147 // Decrement the counter for pending datapath cmds
15148 --iNumPendingDatapathCmd;
15149
15150 if (aDatapathStatus != PVMFSuccess)
15151 {
15152 bool ehPending = CheckForPendingErrorHandlingCmd();
15153 if (ehPending)
15154 {
15155 // there should be no error handling queued.
15156 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathResume() Already EH pending, should never happen"));
15157 return;
15158 }
15159 else
15160 {
15161 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15162 (0, "PVPlayerEngine::HandleDatapathResume() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15163 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15164 if (aCmdResp)
15165 {
15166 if (aCmdResp->GetEventExtensionInterface())
15167 {
15168 nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
15169 }
15170 }
15171
15172 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15173 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
15174 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
15175 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
15176 }
15177 return;
15178 }
15179
15180 if (iNumPendingDatapathCmd == 0)
15181 {
15182 if (iChangePlaybackPositionWhenResuming || iChangePlaybackDirectionWhenResuming)
15183 {
15184 // This should never be happen if Skip on sink node has not completed (i.e. iNumPendingSkipCompleteEvent
15185 // is greater than zero). If this happens with iNumPendingSkipCompleteEvent > 0 then just assert.
15186 // Set the clock to the specified begin time just before Start of playback Clock
15187 iPlaybackClock.Stop();
15188 bool overflow = 0;
15189 iPlaybackClock.SetStartTime32(iSkipMediaDataTS, PVMF_MEDIA_CLOCK_MSEC, overflow);
15190
15191 if (iNumPVMFInfoStartOfDataPending == 0)
15192 {
15193 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
15194 (0, "PVPlayerEngine::HandleDatapathResume() Skipping WatchDogTimer - Starting PlayBackClock"));
15195 StartPlaybackClock();
15196 }
15197 else
15198 {
15199 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
15200 (0, "PVPlayerEngine::HandleDatapathResume() Setting WatchDogTimer for %d ms, TargetNPT=%d ActualNPT=%d",
15201 iWatchDogTimerInterval, iTargetNPT, iActualNPT));
15202
15203 // There can be a case in which WatchDogTimerInterval is zero and iNumPVMFInfoStartOfDataPending is greater than zero.
15204 // In this case it is possible InfoStartofData is not sent by Sink Nodes for some time and player hangs. To avoid the player hang
15205 // set the watchdog timer Interval to the default value of 1 second.
15206 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
15207 iWatchDogTimer->Start();
15208 }
15209
15210 // Set the actual playback position to the requested time since actual media data TS was adjusted
15211 // This is important since the difference between the two is used to calculate the NPT to media data offset
15212 // This is not required here as the ActualPlaybackPosition is already adjusted before calling Skip on Sink Node.
15213 // iActualNPT=iCurrentBeginPosition.iPosValue.millisec_value;
15214
15215 //clear the pending direction change NPT.
15216 iChangeDirectionNPT.iIndeterminate = true;
15217 // Save the start NPT and TS
15218 iStartNPT = iActualNPT;
15219 iStartMediaDataTS = iSkipMediaDataTS;
15220 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO,
15221 (0, "PVPlayerEngine::HandleDatapathResume() TargetNPT %d, ActualNPT %d StartTS %d",
15222 iTargetNPT, iStartNPT, iStartMediaDataTS));
15223 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
15224 (0, "PVPlayerEngine::HandleDatapathResume() TargetNPT %d, ActualNPT %d StartTS %d",
15225 iTargetNPT, iStartNPT, iStartMediaDataTS));
15226
15227 // send the actual playback position from where playback will resume after reposition.
15228 PVPPlaybackPosition actualPlaybackPosition;
15229 actualPlaybackPosition.iPosValue.millisec_value = iStartNPT;
15230 actualPlaybackPosition.iPosUnit = PVPPBPOSUNIT_MILLISEC;
15231
15232 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15233 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoPlaybackFromBeginTime, puuid, NULL));
15234 SendInformationalEvent(PVMFInfoActualPlaybackPosition, OSCL_STATIC_CAST(PVInterface*, infomsg), (OsclAny*)&actualPlaybackPosition);
15235 infomsg->removeRef();
15236 }
15237 else
15238 {
15239 // Resume the playback clock - only if we have come out of any previous auto pause, if any
15240 if (iPlaybackClock.GetState() == PVMFMediaClock::PAUSED)
15241 {
15242 StartPlaybackClock();
15243
15244 // Notify all sink nodes that have sync control IF that clock has started
15245 for (uint32 i = 0; i < iDatapathList.size(); ++i)
15246 {
15247 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
15248 {
15249 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
15250 }
15251 }
15252 }
15253
15254 // Restart the watchdog timer which was cancelled in Pause command.
15255 // this should only be done when engine is waiting for StartofData info event
15256 // after reposition.
15257 if (iNumPVMFInfoStartOfDataPending > 0)
15258 {
15259 if (iWatchDogTimerInterval > 0)
15260 {
15261 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO,
15262 (0, "PVPlayerEngine::HandleDatapathResume Setting WatchDogTimer for %d ms, iNumPVMFInfoStartOfDataPending=%d",
15263 iWatchDogTimerInterval, iNumPVMFInfoStartOfDataPending));
15264 iWatchDogTimer->setTimerDuration(iWatchDogTimerInterval);
15265 iWatchDogTimer->Start();
15266 }
15267 }
15268
15269 // Restart the end time check if enabled
15270 if (iEndTimeCheckEnabled)
15271 {
15272 // Determine the check cycle based on interval setting in milliseconds
15273 // and timer frequency of 100 millisec
15274 int32 checkcycle = iEndTimeCheckInterval / 100;
15275 if (checkcycle == 0)
15276 {
15277 ++checkcycle;
15278 }
15279 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
15280 iPollingCheckTimer->Request(PVPLAYERENGINE_TIMERID_ENDTIMECHECK, 0, checkcycle, this, true);
15281 }
15282 }
15283
15284 SetEngineState(PVP_ENGINE_STATE_STARTED);
15285
15286 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathResume() Report command as completed"));
15287 EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, PVMFSuccess);
15288 }
15289
15290 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathResume() Out"));
15291 }
15292
15293
HandleDatapathStop(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)15294 void PVPlayerEngine::HandleDatapathStop(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
15295 {
15296 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
15297 (0, "PVPlayerEngine::HandleDatapathStop() for %s Tick=%d",
15298 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
15299
15300 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStop() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15301
15302 // Decrement the counter for pending datapath cmds
15303 --iNumPendingDatapathCmd;
15304
15305 if (aDatapathStatus != PVMFSuccess)
15306 {
15307 bool ehPending = CheckForPendingErrorHandlingCmd();
15308 if (ehPending)
15309 {
15310 // there should be no error handling queued.
15311 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStop() Already EH pending, should never happen"));
15312 return;
15313 }
15314 else
15315 {
15316 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15317 (0, "PVPlayerEngine::HandleDatapathStop() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15318 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15319 if (aCmdResp)
15320 {
15321 if (aCmdResp->GetEventExtensionInterface())
15322 {
15323 nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
15324 }
15325 }
15326
15327 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15328 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
15329 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
15330 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
15331 }
15332 return;
15333 }
15334
15335 if (iNumPendingDatapathCmd == 0)
15336 {
15337 // Continue on by stopping the source node
15338 PVMFStatus cmdstatus = DoSourceNodeStop(aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
15339
15340 if (cmdstatus != PVMFSuccess)
15341 {
15342 bool ehPending = CheckForPendingErrorHandlingCmd();
15343 if (ehPending)
15344 {
15345 // there should be no error handling queued.
15346 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStop() Already EH pending, should never happen"));
15347 return;
15348 }
15349 else
15350 {
15351 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathStop() Report command as failed, Add EH command"));
15352 iCommandCompleteErrMsgInErrorHandling = NULL;
15353 iCommandCompleteStatusInErrorHandling = cmdstatus;
15354 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
15355 }
15356 }
15357 }
15358
15359 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathStop() Out"));
15360 }
15361
15362
HandleDatapathTeardown(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)15363 void PVPlayerEngine::HandleDatapathTeardown(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
15364 {
15365 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
15366 (0, "PVPlayerEngine::HandleDatapathTeardown() for %s Tick=%d",
15367 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
15368
15369 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathTeardown() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15370
15371 PVMFStatus cmdstatus;
15372
15373 switch (aDatapathStatus)
15374 {
15375 case PVMFSuccess:
15376 // Reset this datapath next
15377 cmdstatus = DoDatapathReset(*(aDatapathContext.iEngineDatapath), aDatapathContext.iCmdId, aDatapathContext.iCmdContext);
15378 break;
15379
15380 default:
15381 {
15382 bool ehPending = CheckForPendingErrorHandlingCmd();
15383 if (ehPending)
15384 {
15385 // there should be no error handling queued.
15386 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathTeardown() Already EH pending, should never happen"));
15387 return;
15388 }
15389 else
15390 {
15391 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15392 (0, "PVPlayerEngine::HandleDatapathTeardown() In %s Failed, Add EH command", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15393 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15394 if (aCmdResp)
15395 {
15396 if (aCmdResp->GetEventExtensionInterface())
15397 {
15398 nextmsg = GetErrorInfoMessageInterface(*(aCmdResp->GetEventExtensionInterface()));
15399 }
15400 }
15401
15402 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15403 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
15404 iCommandCompleteStatusInErrorHandling = aDatapathStatus;
15405 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP, NULL, NULL, NULL, false);
15406 }
15407 return;
15408 }
15409 }
15410
15411 if (cmdstatus != PVMFSuccess)
15412 {
15413 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDatapathTeardown() Reset failed, asserting"));
15414 OSCL_ASSERT(false);
15415 EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, cmdstatus);
15416 }
15417
15418 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleVideoDatapathTeardown() Out"));
15419 }
15420
15421
HandleDatapathReset(PVPlayerEngineContext & aDatapathContext,PVMFStatus aDatapathStatus,PVMFCmdResp * aCmdResp)15422 void PVPlayerEngine::HandleDatapathReset(PVPlayerEngineContext& aDatapathContext, PVMFStatus aDatapathStatus, PVMFCmdResp* aCmdResp)
15423 {
15424 OSCL_UNUSED_ARG(aCmdResp);
15425
15426 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iPerfLogger, PVLOGMSG_INFO,
15427 (0, "PVPlayerEngine::HandleDatapathReset() for %s Tick=%d",
15428 aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr(), OsclTickCount::TickCount()));
15429
15430 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathReset() In %s", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15431
15432 // Decrement the counter for pending datapath cmds
15433 --iNumPendingDatapathCmd;
15434
15435 if (aDatapathStatus != PVMFSuccess)
15436 {
15437 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15438 (0, "PVPlayerEngine::HandleDatapathReset() In %s Reset failed, assert", aDatapathContext.iEngineDatapath->iTrackInfo->getTrackMimeType().get_cstr()));
15439 OSCL_ASSERT(false);
15440 return;
15441 }
15442 else
15443 {
15444 // Reset for this datapath is complete
15445 //a sync call in engine - no async cmds issued here
15446 DoEngineDatapathTeardown(*(aDatapathContext.iEngineDatapath));
15447 }
15448
15449 //this means datapath reset and teardown is complete for all datapaths
15450 if (iNumPendingDatapathCmd == 0)
15451 {
15452 if (iState == PVP_ENGINE_STATE_RESETTING)
15453 {
15454 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15455 (0, "PVPlayerEngine::HandleDatapathReset() Reset on SourceNode and Datapath completed"));
15456 // Reset on source node and datapath is complete, now need to remove the data sinks and sources
15457 // so schedule engine AO - we cannnot delete datapaths in callback, hence the reschedule
15458 SetEngineState(PVP_ENGINE_STATE_IDLE);
15459 RunIfNotReady();
15460 }
15461 else if (iState == PVP_ENGINE_STATE_STOPPING)
15462 {
15463 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathReset() Stop Completed"));
15464 // stop has completed
15465 SetEngineState(PVP_ENGINE_STATE_INITIALIZED);
15466 EngineCommandCompleted(aDatapathContext.iCmdId, aDatapathContext.iCmdContext, PVMFSuccess);
15467 }
15468 else
15469 {
15470 //engine cannot be in any other state
15471 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15472 (0, "PVPlayerEngine::HandleDatapathReset() Wrong Engine state for Reset to complete, asserting"));
15473 OSCL_ASSERT(false);
15474 }
15475 }
15476
15477 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDatapathReset() Out"));
15478 }
15479
HandleSourceNodeGetLicense(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)15480 void PVPlayerEngine::HandleSourceNodeGetLicense(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
15481 {
15482 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeGetLicense() In"));
15483
15484 switch (aNodeResp.GetCmdStatus())
15485 {
15486 case PVMFSuccess:
15487 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
15488 break;
15489
15490 case PVMFErrCancelled:
15491 default:
15492 {
15493 // report command complete
15494 PVMFStatus cmdstatus = aNodeResp.GetCmdStatus();
15495
15496 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15497 if (aNodeResp.GetEventExtensionInterface())
15498 {
15499 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
15500 }
15501
15502 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15503 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
15504 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg));
15505 errmsg->removeRef();
15506
15507 }
15508 break;
15509 }
15510 /* Set CancelAcquireLicense cmd in current cmd */
15511 if (!iCmdToDlaCancel.empty())
15512 {
15513 iCurrentCmd.push_front(iCmdToDlaCancel[0]);
15514 iCmdToDlaCancel.clear();
15515 }
15516 }
15517
HandleSourceNodeCancelGetLicense(PVPlayerEngineContext & aNodeContext,const PVMFCmdResp & aNodeResp)15518 void PVPlayerEngine::HandleSourceNodeCancelGetLicense(PVPlayerEngineContext& aNodeContext, const PVMFCmdResp& aNodeResp)
15519 {
15520 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeCancelGetLicense() In"));
15521
15522 switch (aNodeResp.GetCmdStatus())
15523 {
15524 case PVMFSuccess:
15525 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, PVMFSuccess);
15526 break;
15527
15528 default:
15529 {
15530 /* report command complete */
15531 PVMFStatus cmdstatus = aNodeResp.GetCmdStatus();
15532
15533 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15534 if (aNodeResp.GetEventExtensionInterface())
15535 {
15536 nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
15537 }
15538
15539 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15540 PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSource, puuid, nextmsg));
15541
15542 if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_CHAR
15543 || iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_ACQUIRE_LICENSE_WCHAR)
15544 {
15545 if (!iCmdToDlaCancel.empty())
15546 {
15547 PVPlayerEngineCommand currentcmd(iCurrentCmd[0]);
15548 iCurrentCmd.erase(iCurrentCmd.begin());
15549 iCurrentCmd.push_front(iCmdToDlaCancel[0]);
15550 /* If we get here the command isn't queued so the cancel fails */
15551 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg));
15552 iCurrentCmd.push_front(currentcmd);
15553 iCmdToDlaCancel.erase(iCmdToDlaCancel.begin());
15554 }
15555 else
15556 {
15557 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeCancelGetLicense() ASSERT"));
15558 OSCL_ASSERT(false);
15559 }
15560 }
15561 else if (iCurrentCmd[0].GetCmdType() == PVP_ENGINE_COMMAND_CANCEL_ACQUIRE_LICENSE)
15562 {
15563 EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg));
15564 }
15565 else
15566 {
15567 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeCancelGetLicense() ASSERT"));
15568 OSCL_ASSERT(false);
15569 }
15570 errmsg->removeRef();
15571 }
15572 break;
15573 }
15574 }
15575
HandleSourceNodeErrorEvent(const PVMFAsyncEvent & aEvent)15576 void PVPlayerEngine::HandleSourceNodeErrorEvent(const PVMFAsyncEvent& aEvent)
15577 {
15578 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() In"));
15579
15580 if (iState == PVP_ENGINE_STATE_RESETTING)
15581 {
15582 //this means error handling, reset or cancelall is still in progress
15583 //no need to look for error event
15584 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15585 (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Return engine in resetting state no need to process the error event"));
15586 return;
15587 }
15588
15589 for (uint32 i = 0; i < iCurrentContextList.size(); ++i)
15590 {
15591 if (iCurrentContextList[i]->iNode)
15592 {
15593 if (iCurrentContextList[i]->iNode == iSourceNode)
15594 {
15595 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15596 (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Cmd Pending on Source node, so src node should not send error events - ignoring err event"));
15597 return;
15598 }
15599 }
15600 }
15601
15602 PVMFEventType event = aEvent.GetEventType();
15603
15604 switch (event)
15605 {
15606 case PVMFErrCorrupt:
15607 case PVMFErrOverflow:
15608 case PVMFErrResource:
15609 case PVMFErrProcessing:
15610 {
15611 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15612 (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Sending PVPlayerErrSourceMediaData for error event %d, Add EH command if not present", event));
15613 bool ehPending = CheckForPendingErrorHandlingCmd();
15614 if (ehPending)
15615 {
15616 // there should be no error handling queued.
15617 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Already EH pending, should never happen"));
15618 return;
15619 }
15620 else
15621 {
15622 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15623 if (aEvent.GetEventExtensionInterface() != NULL)
15624 {
15625 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15626 }
15627 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15628 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceMediaData, puuid, nextmsg));
15629 iCommandCompleteStatusInErrorHandling = event;
15630 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15631 if (iCurrentCmd.empty())
15632 {
15633 // this error was received when no cmd was being processed so send the error event from here
15634 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15635 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15636 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15637 iCommandCompleteErrMsgInErrorHandling->removeRef();
15638 iCommandCompleteErrMsgInErrorHandling = NULL;
15639 }
15640 }
15641 }
15642 break;
15643
15644 case PVMFErrUnderflow:
15645 {
15646 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15647 (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Sending PVPlayerErrSourceMediaDataUnavailable for error event %d, Add EH command if not present", event));
15648 bool ehPending = CheckForPendingErrorHandlingCmd();
15649 if (ehPending)
15650 {
15651 // there should be no error handling queued.
15652 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Already EH pending, should never happen"));
15653 return;
15654 }
15655 else
15656 {
15657 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15658 if (aEvent.GetEventExtensionInterface() != NULL)
15659 {
15660 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15661 }
15662 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15663 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceMediaDataUnavailable, puuid, nextmsg));
15664 iCommandCompleteStatusInErrorHandling = event;
15665 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15666 if (iCurrentCmd.empty())
15667 {
15668 // this error was received when no cmd was being processed so send the error event from here
15669 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15670 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15671 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15672 iCommandCompleteErrMsgInErrorHandling->removeRef();
15673 iCommandCompleteErrMsgInErrorHandling = NULL;
15674 }
15675 }
15676 }
15677 break;
15678
15679 case PVMFErrNoResources:
15680 case PVMFErrResourceConfiguration:
15681 case PVMFErrTimeout:
15682 case PVMFErrNoMemory:
15683 {
15684 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15685 (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Sending PVPlayerErrSourceFatal for error event %d, Add EH command if not present", event));
15686 bool ehPending = CheckForPendingErrorHandlingCmd();
15687 if (ehPending)
15688 {
15689 // there should be no error handling queued.
15690 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Already EH pending, should never happen"));
15691 return;
15692 }
15693 else
15694 {
15695 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15696 if (aEvent.GetEventExtensionInterface() != NULL)
15697 {
15698 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15699 }
15700 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15701 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceFatal, puuid, nextmsg));
15702 iCommandCompleteStatusInErrorHandling = event;
15703 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15704 if (iCurrentCmd.empty())
15705 {
15706 // this error was received when no cmd was being processed so send the error event from here
15707 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15708 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15709 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15710 iCommandCompleteErrMsgInErrorHandling->removeRef();
15711 iCommandCompleteErrMsgInErrorHandling = NULL;
15712 }
15713 }
15714 }
15715 break;
15716
15717 default:
15718 // Do nothing but log it
15719 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Do nothing for this event %d", event));
15720 break;
15721 }
15722
15723 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeErrorEvent() Out"));
15724 }
15725
15726
HandleDecNodeErrorEvent(const PVMFAsyncEvent & aEvent,int32 aDatapathIndex)15727 void PVPlayerEngine::HandleDecNodeErrorEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
15728 {
15729 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() In"));
15730
15731 OSCL_UNUSED_ARG(aDatapathIndex);
15732
15733 if (iState == PVP_ENGINE_STATE_RESETTING)
15734 {
15735 //this means error handling, reset or cancelall is still in progress
15736 //no need to look for error event
15737 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15738 (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Return engine in resetting state no need to process the error event"));
15739 return;
15740 }
15741
15742 PVMFEventType event = aEvent.GetEventType();
15743
15744 switch (event)
15745 {
15746 case PVMFErrCorrupt:
15747 case PVMFErrOverflow:
15748 case PVMFErrUnderflow:
15749 case PVMFErrProcessing:
15750 {
15751 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15752 (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Sending PVPlayerErrDatapathMediaData for error event %d, Add EH command if not present", event));
15753 bool ehPending = CheckForPendingErrorHandlingCmd();
15754 if (ehPending)
15755 {
15756 // there should be no error handling queued.
15757 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Already EH pending, should never happen"));
15758 return;
15759 }
15760 else
15761 {
15762 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15763 if (aEvent.GetEventExtensionInterface() != NULL)
15764 {
15765 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15766 }
15767 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15768 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathMediaData, puuid, nextmsg));
15769 iCommandCompleteStatusInErrorHandling = event;
15770 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15771 if (iCurrentCmd.empty())
15772 {
15773 // this error was received when no cmd was being processed so send the error event from here
15774 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15775 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15776 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15777 iCommandCompleteErrMsgInErrorHandling->removeRef();
15778 iCommandCompleteErrMsgInErrorHandling = NULL;
15779 }
15780 }
15781 }
15782 break;
15783
15784 case PVMFErrTimeout:
15785 case PVMFErrNoResources:
15786 case PVMFErrResourceConfiguration:
15787 case PVMFErrResource:
15788 case PVMFErrNoMemory:
15789 {
15790 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15791 (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Sending PVPlayerErrDatapathFatal for error event %d, Add EH command if not present", event));
15792 bool ehPending = CheckForPendingErrorHandlingCmd();
15793 if (ehPending)
15794 {
15795 // there should be no error handling queued.
15796 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Already EH pending, should never happen"));
15797 return;
15798 }
15799 else
15800 {
15801 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15802 if (aEvent.GetEventExtensionInterface() != NULL)
15803 {
15804 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15805 }
15806 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15807 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrDatapathFatal, puuid, nextmsg));
15808 iCommandCompleteStatusInErrorHandling = event;
15809 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15810 if (iCurrentCmd.empty())
15811 {
15812 // this error was received when no cmd was being processed so send the error event from here
15813 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15814 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15815 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15816 iCommandCompleteErrMsgInErrorHandling->removeRef();
15817 iCommandCompleteErrMsgInErrorHandling = NULL;
15818 }
15819 }
15820 }
15821 break;
15822
15823 default:
15824 // Do nothing but log it
15825 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Do nothing for this event %d", event));
15826 break;
15827 }
15828
15829 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeErrorEvent() Out"));
15830 }
15831
15832
HandleSinkNodeErrorEvent(const PVMFAsyncEvent & aEvent,int32 aDatapathIndex)15833 void PVPlayerEngine::HandleSinkNodeErrorEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
15834 {
15835 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() In"));
15836
15837 OSCL_UNUSED_ARG(aDatapathIndex);
15838
15839 if (iState == PVP_ENGINE_STATE_RESETTING)
15840 {
15841 //this means error handling, reset or cancelall is still in progress
15842 //no need to look for error event
15843 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15844 (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Return engine in resetting state no need to process the error event"));
15845 return;
15846 }
15847
15848 PVMFEventType event = aEvent.GetEventType();
15849
15850 switch (event)
15851 {
15852 case PVMFErrCorrupt:
15853 case PVMFErrOverflow:
15854 case PVMFErrUnderflow:
15855 case PVMFErrProcessing:
15856 {
15857 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15858 (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Sending PVPlayerErrDatapathMediaData for error event %d, Add EH command if not present", event));
15859 bool ehPending = CheckForPendingErrorHandlingCmd();
15860 if (ehPending)
15861 {
15862 // there should be no error handling queued.
15863 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Already EH pending, should never happen"));
15864 return;
15865 }
15866 else
15867 {
15868 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15869 if (aEvent.GetEventExtensionInterface() != NULL)
15870 {
15871 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15872 }
15873 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15874 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkMediaData, puuid, nextmsg));
15875 iCommandCompleteStatusInErrorHandling = event;
15876 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15877 if (iCurrentCmd.empty())
15878 {
15879 // this error was received when no cmd was being processed so send the error event from here
15880 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15881 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15882 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15883 iCommandCompleteErrMsgInErrorHandling->removeRef();
15884 iCommandCompleteErrMsgInErrorHandling = NULL;
15885 }
15886 }
15887 }
15888 break;
15889
15890 case PVMFErrTimeout:
15891 case PVMFErrNoResources:
15892 case PVMFErrResourceConfiguration:
15893 case PVMFErrResource:
15894 case PVMFErrNoMemory:
15895 {
15896 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
15897 (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Sending PVPlayerErrSinkFatal for error event %d, Add EH command if not present", event));
15898 bool ehPending = CheckForPendingErrorHandlingCmd();
15899 if (ehPending)
15900 {
15901 // there should be no error handling queued.
15902 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Already EH pending, should never happen"));
15903 return;
15904 }
15905 else
15906 {
15907 PVMFErrorInfoMessageInterface* nextmsg = NULL;
15908 if (aEvent.GetEventExtensionInterface() != NULL)
15909 {
15910 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
15911 }
15912 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
15913 iCommandCompleteErrMsgInErrorHandling = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSinkFatal, puuid, nextmsg));
15914 iCommandCompleteStatusInErrorHandling = event;
15915 AddCommandToQueue(PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL, NULL, NULL, NULL, false);
15916 if (iCurrentCmd.empty())
15917 {
15918 // this error was received when no cmd was being processed so send the error event from here
15919 SendErrorEvent(iCommandCompleteStatusInErrorHandling,
15920 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling),
15921 aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
15922 iCommandCompleteErrMsgInErrorHandling->removeRef();
15923 iCommandCompleteErrMsgInErrorHandling = NULL;
15924 }
15925 }
15926 }
15927 break;
15928
15929 default:
15930 // Do nothing but log it
15931 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Do nothing for this event %d", event));
15932 break;
15933 }
15934
15935 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeErrorEvent() Out"));
15936 }
15937
15938 //Return val: true means found/deleted cmd(s).
removeCmdFromQ(Oscl_Vector<PVPlayerEngineCommand,OsclMemAllocator> & aVec,const PVPlayerEngineCommandType aCmdType,bool aRemove)15939 bool PVPlayerEngine::removeCmdFromQ(Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> &aVec, const PVPlayerEngineCommandType aCmdType, bool aRemove)
15940 {
15941 if (aVec.size() == 0)
15942 {
15943 return false;
15944 }
15945 // OSCL priority queue doesn't allow index access so will need to
15946 // go through each pending cmd one-by-one, save commands that are not auto-resume
15947 // and put the commands back into the pending queue.
15948 // Vector to hold the pending cmds temporarily
15949 bool ret = false;
15950 Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> tmpvec;
15951 tmpvec.reserve(aVec.size());
15952 tmpvec.clear();
15953 // Go through each pending command
15954
15955 for (int i = aVec.size() - 1; i >= 0; i--)
15956 {
15957 if (aVec[i].GetCmdType() == aCmdType)
15958 {
15959 ret = true;
15960 if (!aRemove)
15961 {
15962 return ret;
15963 }
15964 continue;
15965 }
15966 tmpvec.push_back(aVec[i]);
15967 }
15968 aVec.clear();
15969 // Put the pending commands back in the priqueue
15970 while (tmpvec.empty() == false)
15971 {
15972 aVec.push_front(tmpvec[0]);
15973 tmpvec.erase(tmpvec.begin());
15974 }
15975 return ret;
15976 }
15977
15978 //Return val: true means found/deleted cmd(s).
removeCmdFromQ(OsclPriorityQueue<PVPlayerEngineCommand,OsclMemAllocator,Oscl_Vector<PVPlayerEngineCommand,OsclMemAllocator>,PVPlayerEngineCommandCompareLess> & aVec,const PVPlayerEngineCommandType aCmdType,bool aRemove)15979 bool PVPlayerEngine::removeCmdFromQ(OsclPriorityQueue<PVPlayerEngineCommand, OsclMemAllocator, Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator>, PVPlayerEngineCommandCompareLess> &aVec, const PVPlayerEngineCommandType aCmdType, bool aRemove)
15980 {
15981 // OSCL priority queue doesn't allow index access so will need to
15982 // go through each pending cmd one-by-one, save commands that are not auto-resume
15983 // and put the commands back into the pending queue.
15984 // Vector to hold the pending cmds temporarily
15985 bool ret = false;
15986 Oscl_Vector<PVPlayerEngineCommand, OsclMemAllocator> tmpvec;
15987 tmpvec.reserve(aVec.size());
15988 tmpvec.clear();
15989 // Go through each pending command
15990 while (aVec.empty() == false)
15991 {
15992 if (aVec.top().GetCmdType() == aCmdType)
15993 {
15994 ret = true;
15995 if (!aRemove)
15996 {
15997 return ret;
15998 }
15999 aVec.pop();
16000 continue;
16001 }
16002 tmpvec.push_back(aVec.top());
16003 aVec.pop();
16004 }
16005 // Put the pending commands back in the priqueue
16006 while (tmpvec.empty() == false)
16007 {
16008 aVec.push(tmpvec[0]);
16009 tmpvec.erase(tmpvec.begin());
16010 }
16011 return ret;
16012 }
16013
HandleSourceNodeInfoEvent(const PVMFAsyncEvent & aEvent)16014 void PVPlayerEngine::HandleSourceNodeInfoEvent(const PVMFAsyncEvent& aEvent)
16015 {
16016 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() In"));
16017
16018 if (iState == PVP_ENGINE_STATE_RESETTING)
16019 {
16020 //this means error handling, reset or cancelall is still in progress
16021 //no need to look for info event
16022 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
16023 (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Return engine in resetting state no need to process the info event %d", aEvent.GetEventType()));
16024 return;
16025 }
16026
16027 PVMFEventType event = aEvent.GetEventType();
16028
16029 switch (event)
16030 {
16031 case PVMFInfoBufferingStart:
16032 case PVMFInfoBufferingComplete:
16033 case PVMFInfoOverflow:
16034 {
16035 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending buffering event %d", event));
16036 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16037 }
16038 break;
16039
16040 case PVMFInfoBufferingStatus:
16041 {
16042 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending buffering status event %d", event));
16043 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16044 }
16045 break;
16046
16047 case PVMFInfoUnderflow:
16048 {
16049 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received PVMFInfoUnderflow"));
16050 // remove pending auto-resume if there is any
16051 if (removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, true))
16052 {
16053 //cancelled the pending auto-resume
16054 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() PVMFInfoUnderflow got cancelled"));
16055 break;
16056 }
16057
16058 // if no auto-pause in the queue and no auto-pause in progress, add one
16059 if ((! removeCmdFromQ(iCurrentCmd, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, false))
16060 && (! removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, false)))
16061 {
16062 AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, NULL, NULL, NULL, false);
16063 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received source underflow event, issue auto-pause command"));
16064 }
16065 }
16066 break;
16067
16068 case PVMFInfoDataReady:
16069 {
16070 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received PVMFInfoDataReady"));
16071 // remove pending auto-pause if there is any
16072 if (removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_PAUSE_DUE_TO_BUFFER_UNDERFLOW, true))
16073 {
16074 //cancelled the pending auto-pause
16075 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() PVMFInfoDataReady got cancelled"));
16076 break;
16077 }
16078
16079 // if no resume in the queue and no resume in progress, add one
16080 if ((! removeCmdFromQ(iCurrentCmd, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, false))
16081 && (! removeCmdFromQ(iPendingCmds, PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, false)))
16082 {
16083 AddCommandToQueue(PVP_ENGINE_COMMAND_RESUME_DUE_TO_BUFFER_DATAREADY, NULL, NULL, NULL, false);
16084 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received source data ready event, issue auto-resume command"));
16085 }
16086 }
16087 break;
16088
16089 case PVMFInfoContentLength:
16090 case PVMFInfoContentType:
16091 case PVMFInfoContentTruncated:
16092 case PVMFInfoRemoteSourceNotification:
16093 case PVMFInfoPlayListClipTransition:
16094 case PVMFInfoPlayListSwitch:
16095 {
16096 PVInterface* intf = NULL;
16097 PVMFBasicErrorInfoMessage* infomsg = NULL;
16098 PVMFErrorInfoMessageInterface* nextmsg = NULL;
16099 if (aEvent.GetEventExtensionInterface() != NULL)
16100 {
16101 nextmsg = GetErrorInfoMessageInterface(*(aEvent.GetEventExtensionInterface()));
16102 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
16103 infomsg =
16104 OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoSourceMediaData,
16105 puuid,
16106 nextmsg));
16107 intf = OSCL_STATIC_CAST(PVInterface*, infomsg);
16108 }
16109 SendInformationalEvent(event, intf, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16110 if (infomsg != NULL)
16111 {
16112 infomsg->removeRef();
16113 }
16114 infomsg = NULL;
16115 }
16116 break;
16117
16118 case PVMFInfoTrackDisable:
16119 {
16120 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending bad track disabled event %d", event));
16121 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16122 }
16123 break;
16124
16125 case PVMFInfoUnexpectedData:
16126 {
16127 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending unexpected data event %d", event));
16128 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16129 }
16130 break;
16131
16132 case PVMFInfoSessionDisconnect:
16133 {
16134 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending session disconnect %d", event));
16135 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16136 }
16137 break;
16138 case PVMFInfoMetadataAvailable:
16139 {
16140 PVUuid infomsguuid = PVMFMetadataInfoMessageInterfaceUUID;
16141 PVMFMetadataInfoMessageInterface* eventMsg = NULL;
16142 PVInterface* infoExtInterface = aEvent.GetEventExtensionInterface();
16143 if (infoExtInterface &&
16144 infoExtInterface->queryInterface(infomsguuid, (PVInterface*&)eventMsg))
16145 {
16146 PVUuid eventuuid;
16147 int32 infoCode;
16148 eventMsg->GetCodeUUID(infoCode, eventuuid);
16149 if (eventuuid == infomsguuid)
16150 {
16151 Oscl_Vector<PvmiKvp, OsclMemAllocator> kvpVector = eventMsg->GetMetadataVector();
16152 SendInformationalEvent(aEvent.GetEventType(), infoExtInterface, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16153 }
16154 }
16155 }
16156 break;
16157 case PVMFInfoDurationAvailable:
16158 {
16159 PVUuid infomsguuid = PVMFDurationInfoMessageInterfaceUUID;
16160 PVMFDurationInfoMessageInterface* eventMsg = NULL;
16161 PVInterface* infoExtInterface = aEvent.GetEventExtensionInterface();
16162 PVInterface* temp = NULL;
16163 if (infoExtInterface &&
16164 infoExtInterface->queryInterface(infomsguuid, temp))
16165 {
16166 PVUuid eventuuid;
16167 int32 infoCode;
16168 eventMsg = OSCL_STATIC_CAST(PVMFDurationInfoMessageInterface*, temp);
16169 eventMsg->GetCodeUUID(infoCode, eventuuid);
16170 if (eventuuid == infomsguuid)
16171 {
16172 iSourceDurationInMS = eventMsg->GetDuration();
16173 iSourceDurationAvailable = true;
16174 SendInformationalEvent(aEvent.GetEventType(), infoExtInterface, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16175 }
16176 }
16177 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending duration available %d", event));
16178 }
16179 break;
16180
16181 case PVMFInfoPoorlyInterleavedContent:
16182 {
16183 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Sending Poorly Interleaved Content Info %d", event));
16184 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16185 }
16186 break;
16187 case PVMFInfoSourceOverflow:
16188 {
16189 PVPPlaybackPosition aBeginPos;
16190 aBeginPos.iIndeterminate = false;
16191 aBeginPos.iPosUnit = PVPPBPOSUNIT_MILLISEC;
16192 aBeginPos.iPosValue.millisec_value = 0;
16193 PVPPlaybackPosition aEndPos;
16194 aEndPos.iIndeterminate = true;
16195 iOverflowFlag = true;
16196 SetPlaybackRange(aBeginPos, aEndPos, false);
16197 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Received source overflow event, issue auto-reposition command"));
16198 }
16199 break;
16200 case PVMFInfoEndOfData:
16201 default:
16202 // Do nothing but log it
16203 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Do nothing for this event %d", event));
16204 break;
16205 }
16206
16207 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSourceNodeInfoEvent() Out"));
16208 }
16209
16210
HandleDecNodeInfoEvent(const PVMFAsyncEvent & aEvent,int32 aDatapathIndex)16211 void PVPlayerEngine::HandleDecNodeInfoEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
16212 {
16213 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() In"));
16214
16215 if (iState == PVP_ENGINE_STATE_RESETTING)
16216 {
16217 //this means error handling, reset or cancelall is still in progress
16218 //no need to look for info event
16219 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
16220 (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Return engine in resetting state no need to process the info event %d", aEvent.GetEventType()));
16221 return;
16222 }
16223
16224 OSCL_UNUSED_ARG(aDatapathIndex);
16225
16226 PVMFEventType event = aEvent.GetEventType();
16227
16228 switch (event)
16229 {
16230 case PVMFInfoProcessingFailure:
16231
16232 SendInformationalEvent(PVMFInfoProcessingFailure);
16233 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Report ProcessingFailure event %d", event));
16234 break;
16235
16236 case PVMFInfoOverflow:
16237 case PVMFInfoEndOfData:
16238 default:
16239 // Do nothing but log it
16240 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Do nothing for this event %d", event));
16241 break;
16242 }
16243
16244 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleDecNodeInfoEvent() Out"));
16245 }
16246
16247
HandleSinkNodeInfoEvent(const PVMFAsyncEvent & aEvent,int32 aDatapathIndex)16248 void PVPlayerEngine::HandleSinkNodeInfoEvent(const PVMFAsyncEvent& aEvent, int32 aDatapathIndex)
16249 {
16250 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() In"));
16251
16252 if (iState == PVP_ENGINE_STATE_RESETTING)
16253 {
16254 //this means error handling, reset or cancelall is still in progress
16255 //no need to look for info event
16256 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
16257 (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Return engine in resetting state no need to process the info event %d", aEvent.GetEventType()));
16258 return;
16259 }
16260
16261 PVMFEventType event = aEvent.GetEventType();
16262
16263 switch (event)
16264 {
16265 case PVMFInfoStartOfData:
16266 {
16267 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoStartOfData event received for %s",
16268 iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr()));
16269
16270 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoStartOfData event received for %s, iNumPendingSkipCompleteEvent=%d iNumPVMFInfoStartOfDataPending=%d",
16271 iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr(),
16272 iNumPendingSkipCompleteEvent, iNumPVMFInfoStartOfDataPending));
16273
16274 uint32 *data = (uint32*) aEvent.GetEventData();
16275 uint32 streamID = *data;
16276
16277 if (streamID != iStreamID)
16278 {
16279 // received StartOfData for previous streamId, ignoring these events
16280 break;
16281 }
16282
16283 if (iNumPVMFInfoStartOfDataPending > 0)
16284 {
16285 --iNumPVMFInfoStartOfDataPending;
16286 }
16287
16288 if ((iNumPendingSkipCompleteEvent == 0) && (iNumPVMFInfoStartOfDataPending == 0))
16289 {
16290 if (iWatchDogTimer->IsBusy())
16291 {
16292 iWatchDogTimer->Cancel();
16293 }
16294 //check engine internal state here prior to starting the clock
16295 //this is to make sure that we do not start the clock in case engine is still
16296 //auto-paused (think usecase: auto-pause, setplaybackrange, auto-resume)
16297 if (iState == PVP_ENGINE_STATE_STARTED)
16298 {
16299 // start the clock only if engine is in started state
16300 StartPlaybackClock();
16301 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() - PlayClock Started"));
16302 }
16303 }
16304 //else it could mean duplicate or old PVMFInfoStartOfData, ignore both
16305 }
16306 break;
16307 case PVMFInfoEndOfData:
16308 {
16309 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoEndOfData event received for %s",
16310 iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr()));
16311
16312 uint32 *data = (uint32*) aEvent.GetEventData();
16313 uint32 streamID = *data;
16314
16315 if (streamID != iStreamID)
16316 {
16317 // received EndOfData for previous streamId, ignoring these events
16318 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoEndOfData event received for %s with StreamID=%d, Engine StreamID=%d",
16319 iDatapathList[aDatapathIndex].iTrackInfo->getTrackMimeType().get_cstr(),
16320 streamID, iStreamID));
16321 break;
16322 }
16323
16324 if (iDatapathList[aDatapathIndex].iDatapath && iDatapathList[aDatapathIndex].iEndOfDataReceived == false)
16325 {
16326 iDatapathList[aDatapathIndex].iEndOfDataReceived = true;
16327 // If all datapath received EOS, initiate a pause-due-to-EOS
16328 if (AllDatapathReceivedEndOfData() == true)
16329 {
16330 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Issue Pause due to end of clip"));
16331 AddCommandToQueue(PVP_ENGINE_COMMAND_PAUSE_DUE_TO_ENDOFCLIP, NULL, NULL, NULL, false);
16332 }
16333 }
16334 else
16335 {
16336 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoEndOfData event received for non-active or already-ended datapath. Asserting"));
16337 OSCL_ASSERT(false);
16338 }
16339 }
16340 break;
16341
16342 case PVMFInfoDataDiscarded:
16343 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoDataDiscarded event received"));
16344 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16345 break;
16346
16347 case PVMFInfoVideoTrackFallingBehind:
16348 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() PVMFInfoVideoTrackFallingBehind event received"));
16349 SendInformationalEvent(event, NULL, aEvent.GetEventData(), aEvent.GetLocalBuffer(), aEvent.GetLocalBufferSize());
16350 break;
16351
16352 default:
16353 // Do nothing but log it
16354 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Do nothing for this event %d", event));
16355 break;
16356 }
16357
16358 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::HandleSinkNodeInfoEvent() Out"));
16359 }
16360
16361
AllDatapathReceivedEndOfData()16362 bool PVPlayerEngine::AllDatapathReceivedEndOfData()
16363 {
16364 // Return false if any active datapath hasn't
16365 // received EOS yet. Else true.
16366 for (uint32 i = 0; i < iDatapathList.size(); ++i)
16367 {
16368 if (iDatapathList[i].iDatapath &&
16369 iDatapathList[i].iEndOfDataReceived == false)
16370 {
16371 return false;
16372 }
16373 }
16374
16375 return true;
16376 }
16377
16378
SendEndOfClipInfoEvent(PVMFStatus aStatus,PVInterface * aExtInterface)16379 void PVPlayerEngine::SendEndOfClipInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
16380 {
16381 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndOfClipInfoEvent() In"));
16382
16383 // If paused succeeded or already paused
16384 if (aStatus == PVMFSuccess || aStatus == PVMFErrInvalidState)
16385 {
16386 // Set the flag so we can disable resume unless user stops, repositions, or changes directrion
16387 iPlaybackPausedDueToEndOfClip = true;
16388
16389 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
16390 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoEndOfClipReached, puuid, NULL));
16391 SendInformationalEvent(PVMFInfoEndOfData, OSCL_STATIC_CAST(PVInterface*, infomsg));
16392 infomsg->removeRef();
16393 }
16394 else
16395 {
16396 SendErrorEvent(aStatus, aExtInterface);
16397 }
16398
16399 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndOfClipInfoEvent() Out"));
16400 }
16401
16402
SendEndTimeReachedInfoEvent(PVMFStatus aStatus,PVInterface * aExtInterface)16403 void PVPlayerEngine::SendEndTimeReachedInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
16404 {
16405 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndTimeReachedInfoEvent() In"));
16406
16407 if (aStatus == PVMFSuccess)
16408 {
16409 PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
16410 PVMFBasicErrorInfoMessage* infomsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerInfoEndTimeReached, puuid, NULL));
16411 SendInformationalEvent(PVMFInfoEndOfData, OSCL_STATIC_CAST(PVInterface*, infomsg));
16412 infomsg->removeRef();
16413 }
16414 else
16415 {
16416 SendErrorEvent(aStatus, aExtInterface);
16417 }
16418
16419 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendEndTimeReachedInfoEvent() Out"));
16420 }
16421
16422
SendSourceUnderflowInfoEvent(PVMFStatus aStatus,PVInterface * aExtInterface)16423 void PVPlayerEngine::SendSourceUnderflowInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
16424 {
16425 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceUnderflowInfoEvent() In"));
16426
16427 if (aStatus == PVMFSuccess || aStatus == PVMFErrNotSupported)
16428 {
16429 if (iDataReadySent)
16430 {
16431 iDataReadySent = false;
16432 SendInformationalEvent(PVMFInfoUnderflow);
16433 }
16434 }
16435 else if (aStatus == PVMFErrCancelled)
16436 {
16437 // Do nothing since the auto-pause was cancelled
16438 }
16439 else
16440 {
16441 SendErrorEvent(aStatus, aExtInterface);
16442 }
16443
16444 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceUnderflowInfoEvent() Out"));
16445 }
16446
16447
SendSourceDataReadyInfoEvent(PVMFStatus aStatus,PVInterface * aExtInterface)16448 void PVPlayerEngine::SendSourceDataReadyInfoEvent(PVMFStatus aStatus, PVInterface* aExtInterface)
16449 {
16450 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceDataReadyInfoEvent() In"));
16451
16452
16453 if (aStatus == PVMFSuccess || aStatus == PVMFErrNotSupported)
16454 {
16455 // send DataReady event only if it is not sent earlier and if EOS is not reported.
16456 // It is possible that for Streaming repositioning to end use-cases engine receives
16457 // EOS before prepare completes, in that case suppress DataReady event.
16458 if (!iDataReadySent && !iPlaybackPausedDueToEndOfClip)
16459 {
16460 iDataReadySent = true;
16461 SendInformationalEvent(PVMFInfoDataReady);
16462 }
16463 }
16464 else if (aStatus == PVMFErrCancelled)
16465 {
16466 // Do nothing since the auto-resume was cancelled
16467 }
16468 else
16469 {
16470 SendErrorEvent(aStatus, aExtInterface);
16471 }
16472
16473 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::SendSourceDataReadyInfoEvent() Out"));
16474 }
16475
16476
GetErrorInfoMessageInterface(PVInterface & aInterface)16477 PVMFErrorInfoMessageInterface* PVPlayerEngine::GetErrorInfoMessageInterface(PVInterface& aInterface)
16478 {
16479 PVMFErrorInfoMessageInterface* extiface = NULL;
16480 PVInterface* temp = NULL;
16481 if (aInterface.queryInterface(PVMFErrorInfoMessageInterfaceUUID, temp))
16482 {
16483 extiface = OSCL_STATIC_CAST(PVMFErrorInfoMessageInterface*, temp);
16484 return extiface;
16485 }
16486 else
16487 {
16488 return NULL;
16489 }
16490 }
16491
16492
StartPlaybackStatusTimer(void)16493 void PVPlayerEngine::StartPlaybackStatusTimer(void)
16494 {
16495 // Check if playback position reporting is enabled
16496 if (!iPBPosEnable || iPlayStatusTimerEnabled)
16497 return;
16498 // To get regular play status events
16499 iPlayStatusTimerEnabled = true;
16500
16501 iClockNotificationsInf->SetCallbackDeltaTime(iPBPosStatusInterval,
16502 iPlayStatusCallbackTimerMarginWindow, (PVMFMediaClockNotificationsObs*)this, false, NULL,
16503 iPlayStatusCallbackTimerID);
16504 }
16505
16506
StopPlaybackStatusTimer(void)16507 void PVPlayerEngine::StopPlaybackStatusTimer(void)
16508 {
16509
16510 // Stop the playback position status timer
16511 iPlayStatusTimerEnabled = false;
16512 if (iClockNotificationsInf && iPlayStatusCallbackTimerID)
16513 {
16514 iClockNotificationsInf->CancelCallback(iPlayStatusCallbackTimerID, false);
16515 iPlayStatusCallbackTimerID = 0;
16516 }
16517 }
16518
CheckForSourceRollOver()16519 bool PVPlayerEngine::CheckForSourceRollOver()
16520 {
16521 uint32 alternates = iDataSource->GetNumAlternateSourceFormatTypes();
16522 if ((alternates > 0) && (iAlternateSrcFormatIndex < alternates))
16523 {
16524 return true;
16525 }
16526 return false;
16527 }
16528
SetupDataSourceForUnknownURLAccess()16529 PVMFStatus PVPlayerEngine::SetupDataSourceForUnknownURLAccess()
16530 {
16531 if (iDataSource == NULL)
16532 {
16533 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - No Data Source"));
16534 return PVMFErrInvalidState;
16535 }
16536 else
16537 {
16538 /*
16539 * In case of unknown url, here is the sequence that engine would attempt:
16540 * 1) First Alternate source format would be PVMF_DATA_SOURCE_RTSP_URL,
16541 * implying that we would attempt a RTSP streaming session
16542 *
16543 * 2) Primary source format would be set to PVMF_DATA_SOURCE_HTTP_URL,
16544 * implying that we would attempt a progressive download first.
16545 *
16546 * 3) Second Alternate source format would be PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL,
16547 * implying that we would attempt a real media cloaking session
16548 *
16549 * 4) Third alternate source format would be PVMF_DATA_SOURCE_MS_HTTP_STREAMING_URL,
16550 * implying that we would attempt a MS HTTP streaming session
16551 */
16552 iSourceFormatType = PVMF_MIME_DATA_SOURCE_RTSP_URL; ;
16553 if (iDataSource->SetAlternateSourceFormatType(PVMF_MIME_DATA_SOURCE_HTTP_URL) != true)
16554 {
16555 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - SetAlternateSourceFormatType Failed"));
16556 return PVMFFailure;
16557 }
16558 if (iDataSource->SetAlternateSourceFormatType(PVMF_MIME_DATA_SOURCE_REAL_HTTP_CLOAKING_URL) != true)
16559 {
16560 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - SetAlternateSourceFormatType Failed"));
16561 return PVMFFailure;
16562 }
16563 if (iDataSource->SetAlternateSourceFormatType(PVMF_MIME_DATA_SOURCE_MS_HTTP_STREAMING_URL) != true)
16564 {
16565 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetupDataSourceForUnknownURLAccess() - SetAlternateSourceFormatType Failed"));
16566 return PVMFFailure;
16567 }
16568 return PVMFSuccess;
16569 }
16570 }
16571
16572 /* scan thru aKvpValue, create a new PvmiKvp object and push
16573 * than onto iPvmiKvpCapNConfig.
16574 * return PVMFSuccess unless allocation error
16575 */
VerifyAndSaveKVPValues(PvmiKvp * aKvpValue)16576 PVMFStatus PVPlayerEngine:: VerifyAndSaveKVPValues(PvmiKvp *aKvpValue)
16577 {
16578
16579 PvmiKvp* KvpCapNConfig = (PvmiKvp *)OSCL_MALLOC(sizeof(PvmiKvp));
16580 if (! KvpCapNConfig) return PVMFErrNoMemory;
16581 oscl_memcpy(KvpCapNConfig, aKvpValue, sizeof(PvmiKvp));
16582
16583
16584 KvpCapNConfig->key = (char*)OSCL_MALLOC(oscl_strlen(aKvpValue->key) + 1);
16585 if (! KvpCapNConfig->key) return PVMFErrNoMemory;
16586 oscl_strncpy(KvpCapNConfig->key, aKvpValue->key, oscl_strlen(aKvpValue->key) + 1);
16587
16588
16589 // all the values have copied automatically so just need to allocate memory of pointer type.
16590
16591 if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=wchar*")) != NULL)
16592 {
16593 KvpCapNConfig->value.pWChar_value = (oscl_wchar*)OSCL_MALLOC((oscl_strlen(aKvpValue->value.pWChar_value) + 1) * sizeof(oscl_wchar));
16594 if (! KvpCapNConfig->value.pWChar_value) return PVMFErrNoMemory;
16595 oscl_strncpy(KvpCapNConfig->value.pWChar_value, aKvpValue->value.pWChar_value, oscl_strlen(aKvpValue->value.pWChar_value) + 1);
16596
16597 }
16598 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=char*")) != NULL)
16599 {
16600 KvpCapNConfig->value.pChar_value = (char*)OSCL_MALLOC(oscl_strlen(aKvpValue->value.pChar_value) + 1);
16601 if (! KvpCapNConfig->value.pChar_value) return PVMFErrNoMemory;
16602 oscl_strncpy(KvpCapNConfig->value.pChar_value, aKvpValue->value.pChar_value, oscl_strlen(aKvpValue->value.pChar_value) + 1);
16603
16604 }
16605 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=uint8*")) != NULL)
16606 {
16607 KvpCapNConfig->value.pUint8_value = (uint8*)OSCL_MALLOC(oscl_strlen((char *)aKvpValue->value.pUint8_value) + 1);
16608 if (! KvpCapNConfig->value.pUint8_value) return PVMFErrNoMemory;
16609 oscl_memcpy(KvpCapNConfig->value.pUint8_value, aKvpValue->value.pUint8_value, oscl_strlen((char *)aKvpValue->value.pUint8_value) + 1);
16610
16611 }
16612 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=int32*")) != NULL)
16613 {
16614 KvpCapNConfig->value.pInt32_value = (int32*)OSCL_MALLOC(sizeof(int32));
16615 if (! KvpCapNConfig->value.pInt32_value) return PVMFErrNoMemory;
16616 oscl_memcpy(KvpCapNConfig->value.pInt32_value, aKvpValue->value.pInt32_value, sizeof(int32));
16617 // @TODO: Future support will be based on length , currently support only one element
16618 }
16619 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=uint32*")) != NULL)
16620 {
16621 KvpCapNConfig->value.pUint32_value = (uint32*)OSCL_MALLOC(sizeof(uint32));
16622 if (! KvpCapNConfig->value.pUint32_value) return PVMFErrNoMemory;
16623 oscl_memcpy(KvpCapNConfig->value.pUint32_value, aKvpValue->value.pUint32_value, sizeof(uint32));
16624 // @TODO: Future support will be based on length, currently support only one element
16625 }
16626 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=int64*")) != NULL)
16627 {
16628 KvpCapNConfig->value.pInt64_value = (int64*)OSCL_MALLOC(sizeof(int64));
16629 if (! KvpCapNConfig->value.pInt64_value) return PVMFErrNoMemory;
16630 oscl_memcpy(KvpCapNConfig->value.pInt64_value, aKvpValue->value.pInt64_value, sizeof(int64));
16631 // @TODO: Future support will be based on length, currently support only one element
16632 }
16633 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=uint64*")) != NULL)
16634 {
16635 KvpCapNConfig->value.pUint64_value = (uint64*)OSCL_MALLOC(sizeof(uint64));
16636 if (! KvpCapNConfig->value.pUint64_value) return PVMFErrNoMemory;
16637 oscl_memcpy(KvpCapNConfig->value.pUint64_value, aKvpValue->value.pUint64_value, sizeof(uint64));
16638 // @TODO: Future support will be based on length, currently support only one element
16639 }
16640 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=float*")) != NULL)
16641 {
16642 KvpCapNConfig->value.pFloat_value = (float*)OSCL_MALLOC(sizeof(float));
16643 if (! KvpCapNConfig->value.pFloat_value) return PVMFErrNoMemory;
16644 oscl_memcpy(KvpCapNConfig->value.pFloat_value, aKvpValue->value.pFloat_value, sizeof(float));
16645 // @TODO: Future support will be based on length, currently support only one element
16646 }
16647 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=double*")) != NULL)
16648 {
16649 KvpCapNConfig->value.pDouble_value = (double*)OSCL_MALLOC(sizeof(double));
16650 if (! KvpCapNConfig->value.pDouble_value) return PVMFErrNoMemory;
16651 oscl_memcpy(KvpCapNConfig->value.pDouble_value, aKvpValue->value.pDouble_value, sizeof(double));
16652 // @TODO: Future support will be based on length, currently support only one element
16653 }
16654 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=range_int32")) != NULL)
16655 {
16656 KvpCapNConfig->value.key_specific_value = (void*)OSCL_MALLOC(sizeof(range_int32));
16657 if (! KvpCapNConfig->value.key_specific_value) return PVMFErrNoMemory;
16658 oscl_memcpy(KvpCapNConfig->value.key_specific_value, aKvpValue->value.key_specific_value, sizeof(range_int32));
16659 // @TODO: Future support will be based on length, currently support only one element
16660 }
16661 else if (oscl_strstr(aKvpValue->key, _STRLIT_CHAR("valtype=range_uint32")) != NULL)
16662 {
16663 KvpCapNConfig->value.key_specific_value = (void*)OSCL_MALLOC(sizeof(range_uint32));
16664 if (! KvpCapNConfig->value.key_specific_value) return PVMFErrNoMemory;
16665 oscl_memcpy(KvpCapNConfig->value.key_specific_value, aKvpValue->value.key_specific_value, sizeof(range_uint32));
16666 // @TODO: Future support will be based on length, currently support only one element
16667 }
16668
16669 iPvmiKvpCapNConfig.push_back(KvpCapNConfig);
16670 return PVMFSuccess;
16671 }
16672
16673
SetRollOverKVPValues()16674 void PVPlayerEngine::SetRollOverKVPValues()
16675 {
16676 PvmiKvp *SaveKvp;
16677 PvmiKvp *ErrorKVP;
16678
16679 for (uint i = 0; i < iPvmiKvpCapNConfig.size(); i++)
16680 {
16681 SaveKvp = iPvmiKvpCapNConfig[i];
16682 setParametersSync(NULL, SaveKvp, 1 , ErrorKVP);
16683
16684 if (ErrorKVP != NULL)
16685 {
16686 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::SetRollOverKVPValues() Configuring cap-config failed"));
16687 }
16688 }
16689
16690 }
16691
DeleteKVPValues()16692 void PVPlayerEngine::DeleteKVPValues()
16693 {
16694 uint i = 0;
16695 while (i < iPvmiKvpCapNConfig.size())
16696 {
16697 PvmiKvp **Setkvp = iPvmiKvpCapNConfig.begin();
16698
16699 if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=wchar*")) != NULL)
16700 {
16701 OSCL_FREE((*Setkvp)->value.pWChar_value);
16702 (*Setkvp)->value.pWChar_value = NULL;
16703
16704 }
16705 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=char*")) != NULL)
16706 {
16707 OSCL_FREE((*Setkvp)->value.pChar_value);
16708 (*Setkvp)->value.pChar_value = NULL;
16709 }
16710 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=uint8*")) != NULL)
16711 {
16712 OSCL_FREE((*Setkvp)->value.pUint8_value);
16713 (*Setkvp)->value.pUint8_value = NULL;
16714 }
16715
16716 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=int32*")) != NULL)
16717 {
16718 OSCL_FREE((*Setkvp)->value.pInt32_value);
16719 (*Setkvp)->value.pInt32_value = NULL;
16720
16721 }
16722 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=uint32*")) != NULL)
16723 {
16724 OSCL_FREE((*Setkvp)->value.pUint32_value);
16725 (*Setkvp)->value.pUint32_value = NULL;
16726
16727 }
16728 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=int64*")) != NULL)
16729 {
16730 OSCL_FREE((*Setkvp)->value.pInt64_value);
16731 (*Setkvp)->value.pInt64_value = NULL;
16732
16733 }
16734 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=uint64*")) != NULL)
16735 {
16736 OSCL_FREE((*Setkvp)->value.pUint64_value);
16737 (*Setkvp)->value.pUint64_value = NULL;
16738 }
16739 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=float*")) != NULL)
16740 {
16741 OSCL_FREE((*Setkvp)->value.pFloat_value);
16742 (*Setkvp)->value.pFloat_value = NULL;
16743 }
16744 else if (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=double*")) != NULL)
16745 {
16746 OSCL_FREE((*Setkvp)->value.pDouble_value);
16747 (*Setkvp)->value.pDouble_value = NULL;
16748 }
16749 else if ((oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=range_int32")) != NULL) ||
16750 (oscl_strstr((*Setkvp)->key, _STRLIT_CHAR("valtype=range_uint32")) != NULL))
16751 {
16752 OSCL_FREE((*Setkvp)->value.key_specific_value);
16753 (*Setkvp)->value.key_specific_value = NULL;
16754 }
16755
16756 OSCL_FREE((*Setkvp)->key);
16757 (*Setkvp)->key = NULL;
16758
16759 OSCL_FREE(*Setkvp);
16760 *Setkvp = NULL;
16761
16762 iPvmiKvpCapNConfig.erase(iPvmiKvpCapNConfig.begin());
16763 }
16764
16765 }
16766
16767
PVPlayerWatchdogTimerEvent()16768 void PVPlayerEngine::PVPlayerWatchdogTimerEvent()
16769 {
16770 //check engine internal state here prior to starting the clock
16771 //this is to make sure that we do not start the clock in case engine is still
16772 //auto-paused (think usecase: auto-pause, setplaybackrange, auto-resume)
16773 if (iState == PVP_ENGINE_STATE_STARTED)
16774 {
16775 // start the clock only if engine is in started state
16776 StartPlaybackClock();
16777 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::PVPlayerWatchdogTimerEvent() WatchDog timer expired"));
16778 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iReposLogger, PVLOGMSG_INFO, (0, "PVPlayerEngine::PVPlayerWatchdogTimerEvent() WatchDog timer expired"));
16779 }
16780 }
16781
StartPlaybackClock()16782 void PVPlayerEngine::StartPlaybackClock()
16783 {
16784 if (iWatchDogTimer->IsBusy())
16785 {
16786 iWatchDogTimer->Cancel();
16787 }
16788
16789 if (iPlaybackClock.GetState() == PVMFMediaClock::RUNNING)
16790 {
16791 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "PVPlayerEngine::StartPlaybackClock() clock already started"));
16792 return;
16793 }
16794
16795 iPlaybackClock.Start();
16796 // Notify all sink nodes that have sync control IF that clock has started
16797 for (uint32 i = 0; i < iDatapathList.size(); ++i)
16798 {
16799 if (iDatapathList[i].iDatapath && iDatapathList[i].iSinkNodeSyncCtrlIF)
16800 {
16801 iDatapathList[i].iSinkNodeSyncCtrlIF->ClockStarted();
16802 }
16803 }
16804
16805 // To get regular play status events
16806 StartPlaybackStatusTimer();
16807
16808 // Restart the end time check if enabled
16809 if (iEndTimeCheckEnabled)
16810 {
16811 // Determine the check cycle based on interval setting in milliseconds
16812 // and timer frequency of 100 millisec
16813 int32 checkcycle = iEndTimeCheckInterval / 100;
16814 if (checkcycle == 0)
16815 {
16816 ++checkcycle;
16817 }
16818 iPollingCheckTimer->Cancel(PVPLAYERENGINE_TIMERID_ENDTIMECHECK);
16819 iPollingCheckTimer->Request(PVPLAYERENGINE_TIMERID_ENDTIMECHECK, 0, checkcycle, this, true);
16820 }
16821
16822 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::StartPlaybackClock() StartNPT %d StartTS %d", iStartNPT, iStartMediaDataTS));
16823 }
16824
GetCompleteList(PVMFMediaPresentationInfo & aList)16825 PVMFStatus PVPlayerEngine::GetCompleteList(PVMFMediaPresentationInfo& aList)
16826 {
16827 if (iSourceNodeTrackSelIF)
16828 {
16829 PVPlayerState state = GetPVPlayerState();
16830 if ((state == PVP_STATE_INITIALIZED) ||
16831 (state == PVP_STATE_PREPARED) ||
16832 (state == PVP_STATE_STARTED) ||
16833 (state == PVP_STATE_PAUSED))
16834 {
16835 aList.Reset();
16836 PVMFStatus retval = PVMFFailure;
16837 int32 leavecode = 0;
16838 OSCL_TRY(leavecode, retval = iSourceNodeTrackSelIF->GetMediaPresentationInfo(aList));
16839 OSCL_FIRST_CATCH_ANY(leavecode,
16840 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetCompleteList() GetMediaPresentationInfo on iSourceNodeTrackSelIF did a leave!"));
16841 return PVMFFailure);
16842 if (retval != PVMFSuccess)
16843 {
16844 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetCompleteList() GetMediaPresentationInfo() call on source node failed"));
16845 }
16846 return retval;
16847 }
16848 }
16849 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetCompleteList() iSourceNodeTrackSelIF Invalid"));
16850 return PVMFFailure;
16851 }
16852
ReleaseCompleteList(PVMFMediaPresentationInfo & aList)16853 PVMFStatus PVPlayerEngine::ReleaseCompleteList(PVMFMediaPresentationInfo& aList)
16854 {
16855 aList.Reset();
16856 return PVMFSuccess;
16857 }
16858
GetPlayableList(PVMFMediaPresentationInfo & aList)16859 PVMFStatus PVPlayerEngine::GetPlayableList(PVMFMediaPresentationInfo& aList)
16860 {
16861 PVPlayerState state = GetPVPlayerState();
16862 if ((state == PVP_STATE_PREPARED) ||
16863 (state == PVP_STATE_STARTED) ||
16864 (state == PVP_STATE_PAUSED))
16865 {
16866 aList = iPlayableList;
16867 if (aList.getNumTracks() == 0)
16868 {
16869 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetPlayableList() No tracks"));
16870 return PVMFFailure;
16871 }
16872 return PVMFSuccess;
16873 }
16874 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetPlayableList() Invalid Engine State"));
16875 return PVMFErrInvalidState;
16876 }
16877
ReleasePlayableList(PVMFMediaPresentationInfo & aList)16878 PVMFStatus PVPlayerEngine::ReleasePlayableList(PVMFMediaPresentationInfo& aList)
16879 {
16880 aList.Reset();
16881 return PVMFSuccess;
16882 }
16883
GetSelectedList(PVMFMediaPresentationInfo & aList)16884 PVMFStatus PVPlayerEngine::GetSelectedList(PVMFMediaPresentationInfo& aList)
16885 {
16886 PVPlayerState state = GetPVPlayerState();
16887 if ((state == PVP_STATE_PREPARED) ||
16888 (state == PVP_STATE_STARTED) ||
16889 (state == PVP_STATE_PAUSED))
16890 {
16891 aList.Reset();
16892 aList.setPresentationType(iPlayableList.getPresentationType());
16893 aList.setSeekableFlag(iPlayableList.IsSeekable());
16894 aList.SetDurationAvailable(iPlayableList.IsDurationAvailable());
16895 aList.setDurationValue(iPlayableList.getDurationValue());
16896 aList.setDurationTimeScale(iPlayableList.getDurationTimeScale());
16897 for (uint32 i = 0; i < iDatapathList.size(); ++i)
16898 {
16899 if (iDatapathList[i].iTrackInfo != NULL)
16900 {
16901 aList.addTrackInfo(*(iDatapathList[i].iTrackInfo));
16902 }
16903 }
16904 if (aList.getNumTracks() == 0)
16905 {
16906 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetSelectedList() No tracks"));
16907 return PVMFFailure;
16908 }
16909 return PVMFSuccess;
16910 }
16911 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::GetSelectedList() Invalid Engine State"));
16912 return PVMFErrInvalidState;
16913 }
16914
ReleaseSelectedList(PVMFMediaPresentationInfo & aList)16915 PVMFStatus PVPlayerEngine::ReleaseSelectedList(PVMFMediaPresentationInfo& aList)
16916 {
16917 aList.Reset();
16918 return PVMFSuccess;
16919 }
16920
RegisterHelperObject(PVMFTrackSelectionHelper * aObject)16921 PVMFStatus PVPlayerEngine::RegisterHelperObject(PVMFTrackSelectionHelper* aObject)
16922 {
16923 if (aObject != NULL)
16924 {
16925 if (iTrackSelectionHelper != NULL)
16926 {
16927 return PVMFErrAlreadyExists;
16928 }
16929 }
16930 iTrackSelectionHelper = aObject;
16931 return PVMFSuccess;
16932 }
16933
ResetReposVariables(bool aResetAll)16934 void PVPlayerEngine::ResetReposVariables(bool aResetAll)
16935 {
16936 if (aResetAll)
16937 {
16938 iStreamID = 0;
16939 }
16940 if (iWatchDogTimer != NULL)
16941 {
16942 if (iWatchDogTimer->IsBusy())
16943 {
16944 iWatchDogTimer->Cancel();
16945 }
16946 }
16947 iNumPendingSkipCompleteEvent = 0;
16948 iNumPVMFInfoStartOfDataPending = 0;
16949 iTargetNPT = 0;
16950 iActualNPT = 0;
16951 iActualMediaDataTS = 0;
16952 iSkipMediaDataTS = 0;
16953 }
16954
DoErrorHandling()16955 PVMFStatus PVPlayerEngine::DoErrorHandling()
16956 {
16957 //pls note that we come into this method twice, in case of error handling
16958 //first time, we come here to start the error handling seq (cancelall if any, followed by reset)
16959 //second time, we come here when all resets are complete to cleanup and send command completes
16960 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoErrorHandling() In"));
16961 // Stop the playback clock
16962 iPlaybackClock.Stop();
16963
16964 // 1st check if anything needs to be cancelled on Source Node or Datapaths
16965 if (!iCurrentContextList.empty())
16966 {
16967 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
16968 (0, "PVPlayerEngine::DoErrorHandling() Some Command is being processed, cancel it"));
16969 for (uint32 i = 0; i < iCurrentContextList.size(); ++i)
16970 {
16971 if (iCurrentContextList[i]->iNode)
16972 {
16973 if (iCurrentContextList[i]->iNode == iSourceNode)
16974 {
16975 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoErrorHandling() Cmd Pending on Source node, should never happend, asserting"));
16976 OSCL_ASSERT(false);
16977 }
16978 }
16979 }
16980
16981 // error handling code set engine state to resetting
16982 SetEngineState(PVP_ENGINE_STATE_RESETTING);
16983 iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
16984 // Since there is a pending node or datapath, cancel it
16985 PVMFStatus status = DoCancelPendingNodeDatapathCommand();
16986 if (status == PVMFPending)
16987 {
16988 // There are some commands which need to be cancelled so wait for cancel complete
16989 // once cancels complete, we would start the reset sequence from either
16990 // NodeCommandComplete, HandlePlayerDataPathEvent, RecognizeComplete
16991 return PVMFPending;
16992 }
16993 // if there is nothing to cancel move forward to reset.
16994 }
16995
16996 // move on to resetting Source Nodes and Datapaths
16997 if (iSourceNode)
16998 {
16999 int32 leavecode = 0;
17000 // call reset on source node if not in created state
17001 if (iSourceNode->GetState() != EPVMFNodeCreated)
17002 {
17003 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
17004 (0, "PVPlayerEngine::DoErrorHandling() Issue reset on Source Node"));
17005 // error handling code set engine state to resetting
17006 SetEngineState(PVP_ENGINE_STATE_RESETTING);
17007 iRollOverState = RollOverStateIdle; //reset roll over state to Idle, as engine is resetting itself
17008
17009 PVPlayerEngineContext* context = AllocateEngineContext(NULL, iSourceNode, NULL, -1, NULL, -1);
17010
17011 PVMFCommandId cmdid = -1;
17012 leavecode = 0;
17013 OSCL_TRY(leavecode, cmdid = iSourceNode->Reset(iSourceNodeSessionId, (OsclAny*)context));
17014 OSCL_FIRST_CATCH_ANY(leavecode,
17015
17016 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
17017 (0, "PVPlayerEngine::DoErrorHandling() Reset on iSourceNode did a leave!"));
17018 FreeEngineContext(context);
17019 OSCL_ASSERT(false);
17020 return PVMFFailure);
17021
17022 return PVMFPending;
17023 }
17024 }
17025
17026 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
17027 (0, "PVPlayerEngine::DoErrorHandling() Source node is deleted or in created state, so start removing sinks"));
17028
17029 // Now delete the datapath.
17030 DoRemoveAllSinks();
17031
17032 // finally do the source node cleanup
17033 if (iDataSource)
17034 {
17035 RemoveDataSourceSync(*iDataSource);
17036 }
17037
17038 SetEngineState(PVP_ENGINE_STATE_IDLE);
17039
17040 // Send the command completion if there is any command in Current command
17041 if (!iCurrentCmd.empty())
17042 {
17043 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
17044 (0, "PVPlayerEngine::DoErrorHandling() Complete the engine command being processed"));
17045 if (iCommandCompleteErrMsgInErrorHandling)
17046 {
17047 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(),
17048 iCurrentCmd[0].GetContext(),
17049 iCommandCompleteStatusInErrorHandling,
17050 OSCL_STATIC_CAST(PVInterface*, iCommandCompleteErrMsgInErrorHandling));
17051 iCommandCompleteErrMsgInErrorHandling->removeRef();
17052 iCommandCompleteErrMsgInErrorHandling = NULL;
17053 }
17054 else
17055 {
17056 EngineCommandCompleted(iCurrentCmd[0].GetCmdId(),
17057 iCurrentCmd[0].GetContext(),
17058 iCommandCompleteStatusInErrorHandling);
17059 }
17060 }
17061
17062 // just send the error handling complete event
17063 SendInformationalEvent(PVMFInfoErrorHandlingComplete, NULL);
17064
17065 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoErrorHandling() Out"));
17066
17067 return PVMFSuccess;
17068 }
17069
CheckForPendingErrorHandlingCmd()17070 bool PVPlayerEngine::CheckForPendingErrorHandlingCmd()
17071 {
17072 //if an error handling cmd had been queued previously
17073 //it must be in top, since error handling cmds have the
17074 //highest priority and pending cmds queue is a priority
17075 //queue
17076 bool retval = false;
17077 if (!iPendingCmds.empty())
17078 {
17079 switch (iPendingCmds.top().GetCmdType())
17080 {
17081 case PVP_ENGINE_COMMAND_ERROR_HANDLING_ADD_DATA_SOURCE:
17082 case PVP_ENGINE_COMMAND_ERROR_HANDLING_INIT:
17083 case PVP_ENGINE_COMMAND_ERROR_HANDLING_PREPARE:
17084 case PVP_ENGINE_COMMAND_ERROR_HANDLING_PAUSE:
17085 case PVP_ENGINE_COMMAND_ERROR_HANDLING_RESUME:
17086 case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RANGE:
17087 case PVP_ENGINE_COMMAND_ERROR_HANDLING_SET_PLAYBACK_RATE:
17088 case PVP_ENGINE_COMMAND_ERROR_HANDLING_STOP:
17089 case PVP_ENGINE_COMMAND_ERROR_HANDLING_CANCEL_ALL_COMMANDS:
17090 case PVP_ENGINE_COMMAND_ERROR_HANDLING_GENERAL:
17091 retval = true;
17092 break;
17093
17094 default:
17095 break;
17096 }
17097 }
17098 return retval;
17099 }
17100
IssueNodeCancelCommand(PVPlayerEngineContext * aCurrentListContext,PVMFSessionId aSessionId,OsclAny * aNumberCancelCmdPending)17101 PVMFStatus PVPlayerEngine::IssueNodeCancelCommand(PVPlayerEngineContext* aCurrentListContext, PVMFSessionId aSessionId, OsclAny* aNumberCancelCmdPending)
17102 {
17103 PVMFStatus leavecode = 0;
17104 OSCL_TRY(leavecode, aCurrentListContext->iNode->CancelAllCommands(aSessionId, aNumberCancelCmdPending));
17105 OSCL_FIRST_CATCH_ANY(leavecode,;);
17106 return leavecode;
17107 }
17108
IssueDatapathCancelCommand(PVPlayerEngineContext * aCurrentListContext,OsclAny * aNumberCancelCmdPending)17109 PVMFStatus PVPlayerEngine::IssueDatapathCancelCommand(PVPlayerEngineContext* aCurrentListContext, OsclAny* aNumberCancelCmdPending)
17110 {
17111 PVMFStatus leavecode = 0;
17112 OSCL_TRY(leavecode, aCurrentListContext->iDatapath->CancelCommand(aNumberCancelCmdPending));
17113 OSCL_FIRST_CATCH_ANY(leavecode,;);
17114 return leavecode;
17115 }
17116
IssueRecognizerRegistryCancel(OsclAny * aNumberCancelCmdPending)17117 PVMFStatus PVPlayerEngine::IssueRecognizerRegistryCancel(OsclAny* aNumberCancelCmdPending)
17118 {
17119 PVMFStatus leavecode = 0;
17120 OSCL_TRY(leavecode, iPlayerRecognizerRegistry.CancelQuery(aNumberCancelCmdPending));
17121 OSCL_FIRST_CATCH_ANY(leavecode,;);
17122 return leavecode;
17123 }
17124
IssueSinkNodeInit(PVPlayerEngineDatapath * aDatapath,OsclAny * aCmdContext,PVMFCommandId & aCmdId)17125 PVMFStatus PVPlayerEngine::IssueSinkNodeInit(PVPlayerEngineDatapath* aDatapath, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
17126 {
17127 PVMFStatus leavecode = 0;
17128 OSCL_TRY(leavecode, aCmdId = aDatapath->iSinkNode->Init(aDatapath->iSinkNodeSessionId, aCmdContext));
17129 OSCL_FIRST_CATCH_ANY(leavecode,;);
17130 return leavecode;
17131 }
17132
IssueSinkNodeReset(PVPlayerEngineDatapath * aDatapath,OsclAny * aCmdContext,PVMFCommandId & aCmdId)17133 PVMFStatus PVPlayerEngine::IssueSinkNodeReset(PVPlayerEngineDatapath* aDatapath, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
17134 {
17135 PVMFStatus leavecode = 0;
17136 OSCL_TRY(leavecode, aCmdId = aDatapath->iSinkNode->Reset(aDatapath->iSinkNodeSessionId, aCmdContext));
17137 OSCL_FIRST_CATCH_ANY(leavecode,;);
17138 return leavecode;
17139 }
17140
IssueSinkSkipMediaData(PVPlayerEngineDatapath * aDatapath,bool aSFR,OsclAny * aCmdContext)17141 PVMFStatus PVPlayerEngine::IssueSinkSkipMediaData(PVPlayerEngineDatapath* aDatapath, bool aSFR, OsclAny* aCmdContext)
17142 {
17143 PVMFStatus leavecode = 0;
17144 OSCL_TRY(leavecode, aDatapath->iSinkNodeSyncCtrlIF->SkipMediaData(aDatapath->iSinkNodeSessionId, iSkipMediaDataTS, iStreamID, aSFR, aCmdContext));
17145 OSCL_FIRST_CATCH_ANY(leavecode,;);
17146 return leavecode;
17147 }
17148
IssueSourceSetDataSourcePosition(bool aIsPosUnitPlayList,OsclAny * aCmdContext)17149 PVMFStatus PVPlayerEngine::IssueSourceSetDataSourcePosition(bool aIsPosUnitPlayList, OsclAny* aCmdContext)
17150 {
17151 PVMFStatus leavecode = 0;
17152 if (aIsPosUnitPlayList)
17153 {
17154 OSCL_TRY(leavecode, iSourceNodePBCtrlIF->SetDataSourcePosition(iSourceNodeSessionId,
17155 iDataSourcePosParams,
17156 aCmdContext));
17157
17158 }
17159 else
17160 {
17161 OSCL_TRY(leavecode, iSourceNodePBCtrlIF->SetDataSourcePosition(iSourceNodeSessionId,
17162 iTargetNPT, iActualNPT, iActualMediaDataTS, iSeekToSyncPoint, iStreamID, aCmdContext));
17163 }
17164 OSCL_FIRST_CATCH_ANY(leavecode,;);
17165 return leavecode;
17166 }
17167
IssueDecNodeInit(PVMFNodeInterface * aNode,PVMFSessionId aDecNodeSessionId,OsclAny * aCmdContext,PVMFCommandId & aCmdId)17168 PVMFStatus PVPlayerEngine::IssueDecNodeInit(PVMFNodeInterface* aNode, PVMFSessionId aDecNodeSessionId, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
17169 {
17170 PVMFStatus leavecode = 0;
17171 OSCL_TRY(leavecode, aCmdId = aNode->Init(aDecNodeSessionId, aCmdContext));
17172 OSCL_FIRST_CATCH_ANY(leavecode,;);
17173 return leavecode;
17174 }
17175
IssueDecNodeReset(PVMFNodeInterface * aNode,PVMFSessionId aDecNodeSessionId,OsclAny * aCmdContext,PVMFCommandId & aCmdId)17176 PVMFStatus PVPlayerEngine::IssueDecNodeReset(PVMFNodeInterface* aNode, PVMFSessionId aDecNodeSessionId, OsclAny* aCmdContext, PVMFCommandId &aCmdId)
17177 {
17178 PVMFStatus leavecode = 0;
17179 OSCL_TRY(leavecode, aCmdId = aNode->Reset(aDecNodeSessionId, aCmdContext));
17180 OSCL_FIRST_CATCH_ANY(leavecode,;);
17181 return leavecode;
17182 }
17183
IssueQueryInterface(PVMFNodeInterface * aNode,PVMFSessionId aSessionId,const PVUuid aUuid,PVInterface * & aInterfacePtr,OsclAny * aCmdContext,PVMFCommandId & aCmdId)17184 PVMFStatus PVPlayerEngine::IssueQueryInterface(PVMFNodeInterface* aNode, PVMFSessionId aSessionId, const PVUuid aUuid, PVInterface*& aInterfacePtr, OsclAny* aCmdContext, PVMFCommandId& aCmdId)
17185 {
17186 PVMFStatus leavecode = 0;
17187 OSCL_TRY(leavecode, aCmdId = aNode->QueryInterface(aSessionId, aUuid, aInterfacePtr, aCmdContext));
17188 OSCL_FIRST_CATCH_ANY(leavecode,;);
17189 return leavecode;
17190 }
17191
17192 OSCL_EXPORT_REF void
GetSDKInfo(PVSDKInfo & aSdkInfo)17193 PVPlayerInterface::GetSDKInfo
17194 (
17195 PVSDKInfo& aSdkInfo
17196 )
17197 {
17198 aSdkInfo.iLabel = PVPLAYER_ENGINE_SDKINFO_LABEL;
17199 aSdkInfo.iDate = PVPLAYER_ENGINE_SDKINFO_DATE;
17200 }
17201
17202 // END FILE
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215