• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec, &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, &paramvec);
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, &paramvec);
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, &paramvec);
339         return DoGetPVPlayerState(cmd, true);
340     }
341     else
342     {
343         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_PVPLAYER_STATE_OOTSYNC, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
490     }
491     else
492     {
493         return AddCommandToQueue(PVP_ENGINE_COMMAND_SET_PLAYBACK_RANGE, (OsclAny*)aContextData, &paramvec, 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, &paramvec);
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, &paramvec);
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, &paramvec);
539         return DoGetCurrentPosition(cmd, true);
540     }
541     else
542     {
543         return DoOOTSyncCommand(PVP_ENGINE_COMMAND_GET_CURRENT_POSITION_OOTSYNC, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
819 
820         // Complete the request synchronously
821         DoCapConfigSetParameters(cmd, true);
822     }
823     else
824     {
825         DoOOTSyncCommand(PVP_ENGINE_COMMAND_CAPCONFIG_SET_PARAMETERS_OOTSYNC, &paramvec);
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, &paramvec, 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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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, &paramvec);
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(&paramkvp[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 = &paramkvp[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 = &paramkvp[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 = &paramkvp[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 = &paramkvp[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 = &paramkvp[paramind];
10260             bool anysuccess = false;
10261 
10262 
10263             if (iSourceNodeCapConfigIF != NULL)
10264             {
10265                 *retkvp = NULL;
10266                 iSourceNodeCapConfigIF->setParametersSync(NULL, &paramkvp[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, &paramkvp[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, &paramkvp[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 = &paramkvp[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