• 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 #ifndef PVMF_JB_JITTERBUFFERMISC_H_INCLUDED
19 #include "pvmf_jitter_buffer_node.h"
20 #endif
21 
22 #ifndef PVMF_JITTER_BUFFER_COMMON_TYPES_H_INCLUDED
23 #include "pvmf_jitter_buffer_common_types.h"
24 #endif
25 
26 
27 #ifndef OSCL_EXCLUSIVE_PTR_H_INCLUDED
28 #include "oscl_exclusive_ptr.h"
29 #endif
30 
31 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
32 #include "pvmf_media_clock.h"
33 #endif
34 
35 #ifndef __MEDIA_CLOCK_CONVERTER_H
36 #include "media_clock_converter.h"
37 #endif
38 
39 #ifndef PVMF_STREAMING_MANAGER_NODE_H_INCLUDED
40 #include "pvmf_jitter_buffer_node.h"
41 #endif
42 
43 #ifndef PVMF_JITTER_BUFFER_FACTORY_H
44 #include "pvmf_jitter_buffer_factory.h"
45 #endif
46 
47 #ifndef PVMF_MEDIA_DATA_H_INCLUDED
48 #include "pvmf_media_data.h"
49 #endif
50 
51 #ifndef PVMF_MEDIA_CMD_H_INCLUDED
52 #include "pvmf_media_cmd.h"
53 #endif
54 
55 #ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
56 #include "pvmf_media_msg_format_ids.h"
57 #endif
58 
59 #ifndef PVLOGGER_H_INCLUDED
60 #include "pvlogger.h"
61 #endif
62 
63 #ifndef PVMF_SM_TUNABLES_H_INCLUDED
64 #include "pvmf_sm_tunables.h"
65 #endif
66 
67 #ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
68 #include "pvmf_basic_errorinfomessage.h"
69 #endif
70 
71 #ifndef OSCL_DLL_H_INCLUDED
72 #include "oscl_dll.h"
73 #endif
74 
75 #ifndef OSCL_MIME_STRING_UTILS_H
76 #include "pv_mime_string_utils.h"
77 #endif
78 
79 #ifndef OSCL_RAND_H_INCLUDED
80 #include "oscl_rand.h"
81 #endif
82 
83 // Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()84 OSCL_DLL_ENTRY_POINT_DEFAULT()
85 
86 //Construction and Destruction
87 OSCL_EXPORT_REF PVMFJitterBufferNode::PVMFJitterBufferNode(int32 aPriority,
88         JitterBufferFactory* aJBFactory): OsclActiveObject(aPriority, "JitterBufferNode")
89 {
90     //Initialize capability
91     iCapability.iCanSupportMultipleInputPorts = true;
92     iCapability.iCanSupportMultipleOutputPorts = true;
93     iCapability.iHasMaxNumberOfPorts = false;
94     iCapability.iMaxNumberOfPorts = 0;//no maximum
95     iCapability.iInputFormatCapability.push_back(PVMF_MIME_RTP);
96     iCapability.iInputFormatCapability.push_back(PVMF_MIME_ASFFF);
97     iCapability.iInputFormatCapability.push_back(PVMF_MIME_RMFF);
98     iCapability.iOutputFormatCapability.push_back(PVMF_MIME_RTP);
99     iCapability.iOutputFormatCapability.push_back(PVMF_MIME_ASFFF);
100     //Jitter buffer factory
101     ipJitterBufferFactory   =   aJBFactory;
102 
103     //Initialize loggers
104     ipLogger = NULL;
105     ipDataPathLogger = NULL;
106     ipDataPathLoggerIn = NULL;
107     ipDataPathLoggerOut = NULL;
108     ipDataPathLoggerFlowCtrl = NULL;
109     ipClockLogger = NULL;
110     ipClockLoggerSessionDuration = NULL;
111     ipClockLoggerRebuff = NULL;
112     ipDiagnosticsLogger = NULL;
113     ipJBEventsClockLogger = NULL;
114 
115     //Diagniostics related
116     iDiagnosticsLogged = false;
117     iNumRunL = 0;
118 
119     Construct();
120     ResetNodeParams(false);
121 }
122 
Construct()123 void PVMFJitterBufferNode::Construct()
124 {
125     //creation and initialization of objects that need to be created on heap in the ctor is done here
126     iInputCommands.Construct(PVMF_JITTER_BUFFER_NODE_COMMAND_ID_START,
127                              PVMF_JITTER_BUFFER_VECTOR_RESERVE);
128     iCurrentCommand.Construct(0, 1);
129 
130     iPortVector.Construct(PVMF_JITTER_BUFFER_NODE_PORT_VECTOR_RESERVE);
131 }
132 
ResetNodeParams(bool aReleaseMemory)133 void PVMFJitterBufferNode::ResetNodeParams(bool aReleaseMemory)
134 {
135     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ResetNodeParams In aReleaseMemory[%d]", aReleaseMemory));
136     //Session specific initializations and resetting
137 
138     oStartPending = false;
139     oStopOutputPorts = true;
140     iPauseTime = 0;
141     ipClientPlayBackClock = NULL;
142     iMediaReceiveingChannelPrepared = false;
143 
144     iBroadCastSession = false;
145 
146     iDelayEstablished = false;
147     iJitterBufferState = PVMF_JITTER_BUFFER_READY;
148     iJitterDelayPercent = 0;
149 
150     //Extension interface initializations
151     if (ipExtensionInterface && aReleaseMemory)
152     {
153         ipExtensionInterface->removeRef();
154     }
155     ipExtensionInterface = NULL;
156 
157     //Variables to persist info passed on by the extension interface
158     iRebufferingThreshold = DEFAULT_JITTER_BUFFER_UNDERFLOW_THRESHOLD_IN_MS;
159     iJitterBufferDurationInMilliSeconds = DEFAULT_JITTER_BUFFER_DURATION_IN_MS;
160     iMaxInactivityDurationForMediaInMs = DEFAULT_MAX_INACTIVITY_DURATION_IN_MS;
161     iEstimatedServerKeepAheadInMilliSeconds = DEFAULT_ESTIMATED_SERVER_KEEPAHEAD_FOR_OOO_SYNC_IN_MS;
162 
163     iJitterBufferSz = 0;
164     iMaxNumBufferResizes = DEFAULT_MAX_NUM_SOCKETMEMPOOL_RESIZES;
165     iBufferResizeSize = DEFAULT_MAX_SOCKETMEMPOOL_RESIZELEN_INPUT_PORT;
166     iBufferingStatusIntervalInMs =
167         (PVMF_JITTER_BUFFER_BUFFERING_STATUS_EVENT_CYCLES * 1000) / PVMF_JITTER_BUFFER_BUFFERING_STATUS_EVENT_FREQUENCY;
168 
169     iDisableFireWallPackets = false;
170     //iPlayingAfterSeek = false;
171 
172     //Event Notifier initialization/reseting
173     iIncomingMediaInactivityDurationCallBkId = 0;
174     iIncomingMediaInactivityDurationCallBkPending = false;
175     iNotifyBufferingStatusCallBkId = 0;
176     iNotifyBufferingStatusCallBkPending = false;
177 
178 
179     if (aReleaseMemory)
180     {
181         if (ipJitterBufferMisc)
182             OSCL_DELETE(ipJitterBufferMisc);
183     }
184 
185     ipJitterBufferMisc = NULL;
186     ipEventNotifier = NULL;
187 
188 
189     /* Clear queued messages in ports */
190     uint32 i;
191     for (i = 0; i < iPortVector.size(); i++)
192     {
193         PVMFJitterBufferPortParams* pPortParams = NULL;
194         bool bRet = getPortContainer(iPortVector[i], pPortParams);
195         if (bRet)
196         {
197             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
198             {
199                 pPortParams->ipJitterBuffer->ResetJitterBuffer();
200             }
201 
202             pPortParams->ResetParams();
203         }
204         iPortVector[i]->ClearMsgQueues();
205     }
206 
207     //Cleaning up of conatiner objects
208     /* delete corresponding port params */
209 
210     if (aReleaseMemory)
211     {
212         //port vect and port params Q
213         Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
214         for (it = iPortParamsQueue.begin();
215                 it != iPortParamsQueue.end();
216                 it++)
217         {
218             PVMFJitterBufferPortParams* pPortParams = *it;
219 
220             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
221             {
222                 if (ipJitterBufferFactory)
223                     ipJitterBufferFactory->Destroy(pPortParams->ipJitterBuffer);
224             }
225 
226             OSCL_DELETE(&pPortParams->irPort);
227             OSCL_DELETE(pPortParams);
228         }
229         iPortParamsQueue.clear();
230         iPortVector.clear();
231         iPortVector.Reconstruct();
232     }
233 
234     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ResetNodeParams Out -"));
235     return;
236 }
237 
~PVMFJitterBufferNode()238 PVMFJitterBufferNode::~PVMFJitterBufferNode()
239 {
240     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::~PVMFJitterBufferNode In"));
241     LogSessionDiagnostics();
242     ResetNodeParams();
243 
244     /*
245      * Cleanup commands
246      * The command queues are self-deleting, but we want to
247      * notify the observer of unprocessed commands.
248      */
249     while (!iCurrentCommand.empty())
250     {
251         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
252     }
253     while (!iInputCommands.empty())
254     {
255         CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
256     }
257 
258     Cancel();
259     /* thread logoff */
260     if (IsAdded())
261         RemoveFromScheduler();
262     CleanUp();
263     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::~PVMFJitterBufferNode Out"));
264 }
265 
CleanUp()266 void PVMFJitterBufferNode::CleanUp()    //Reverse of Construct
267 {
268     //noop
269 }
270 
271 ///////////////////////////////////////////////////////////////////////////////
272 //Implementation of overrides from PVInterface
273 ///////////////////////////////////////////////////////////////////////////////
274 
275 ///////////////////////////////////////////////////////////////////////////////
276 //Checks if the instance of PVMFJitterBufferExtensionInterfaceImpl is existing
277 //If existing: Query from this interface if UUID mentioned is supported
278 //If not existing: Instantiate PVMFJitterBufferExtensionInterfaceImpl
279 //and query requested interface from the PVMFJitterBufferExtensionInterfaceImpl
280 //Return Values:true/false
281 //Leave Codes: OsclErrNoMemory
282 //Leave Condition: If instance of PVMFJitterBufferExtensionInterfaceImpl cannot
283 //be instantiated.
284 ///////////////////////////////////////////////////////////////////////////////
queryInterface(const PVUuid & uuid,PVInterface * & iface)285 bool PVMFJitterBufferNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
286 {
287     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::queryInterface In"));
288     iface = NULL;
289     if (uuid == PVUuid(PVMF_JITTERBUFFERNODE_EXTENSIONINTERFACE_UUID))
290     {
291         if (!ipExtensionInterface)
292         {
293             OsclMemAllocator alloc;
294             int32 err;
295             OsclAny*ptr = NULL;
296             OSCL_TRY(err,
297                      ptr = alloc.ALLOCATE(sizeof(PVMFJitterBufferExtensionInterfaceImpl));
298                     );
299             if (err != OsclErrNone || !ptr)
300             {
301                 PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::queryInterface: Error - Out of memory"));
302                 OSCL_LEAVE(OsclErrNoMemory);
303             }
304             ipExtensionInterface =
305                 OSCL_PLACEMENT_NEW(ptr, PVMFJitterBufferExtensionInterfaceImpl(this));
306         }
307         return (ipExtensionInterface->queryInterface(uuid, iface));
308     }
309     else
310     {
311         return false;
312     }
313 }
314 
315 ///////////////////////////////////////////////////////////////////////////////
316 //Implementation  of overrides from PVMFNodeInterface
317 ///////////////////////////////////////////////////////////////////////////////
318 
319 ///////////////////////////////////////////////////////////////////////////////
320 //Does thread-specific node creation and go to "Idle" state.
321 //Creates logger objects
322 //Adds the AO to the scheduler
323 //Return values: PVMFSuccess/PVMFErrInvalidState
324 //PVMFSuccess: If API call is successful and was made in EPVMFNodeCreated state
325 //PVMFErrInvalidState: If API is called in the invalid state
326 //Leave Codes: NA
327 ///////////////////////////////////////////////////////////////////////////////
ThreadLogon()328 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferNode::ThreadLogon()
329 {
330     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ThreadLogon In"));
331     PVMFStatus status;
332 
333     switch (iInterfaceState)
334     {
335         case EPVMFNodeCreated:
336         {
337             if (!IsAdded())
338                 AddToScheduler();
339 
340             ipLogger = PVLogger::GetLoggerObject("jitterbuffernode");
341             ipDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffernode");
342             ipDataPathLoggerIn = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffernode.in");
343             ipDataPathLoggerOut = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffernode.out");
344             ipDataPathLoggerFlowCtrl = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffernode.flowctrl");
345 
346             ipClockLogger = PVLogger::GetLoggerObject("clock.jitterbuffernode");
347             ipClockLoggerSessionDuration = PVLogger::GetLoggerObject("clock.streaming_manager.sessionduration");
348             ipClockLoggerRebuff = PVLogger::GetLoggerObject("clock.jitterbuffernode.rebuffer");
349 
350             ipDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.streamingmanager");
351             ipJBEventsClockLogger = PVLogger::GetLoggerObject("jitterbuffernode.eventsclock");
352 
353             iDiagnosticsLogged = false;
354             SetState(EPVMFNodeIdle);
355             status = PVMFSuccess;
356         }
357         break;
358         default:
359             status = PVMFErrInvalidState;
360             break;
361     }
362 
363     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ThreadLogon Out retval - %d", status));
364     return status;
365 }
366 
367 ///////////////////////////////////////////////////////////////////////////////
368 //Does thread-specific node cleanup and go to "Created" state.
369 //Releases logger objects
370 //Removes the AO to the scheduler
371 //Return values: PVMFSuccess/PVMFErrInvalidState
372 //PVMFSuccess: If API call is successful and was made in EPVMFNodeIdle state
373 //PVMFErrInvalidState: If API is called in the invalid state
374 //Leave Codes: NA
375 ///////////////////////////////////////////////////////////////////////////////
ThreadLogoff()376 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferNode::ThreadLogoff()
377 {
378     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ThreadLogoff In"));
379     PVMFStatus status = PVMFFailure;
380 
381     switch (iInterfaceState)
382     {
383         case EPVMFNodeIdle:
384         {
385             ResetNodeParams();
386             ipLogger = NULL;
387             ipDataPathLogger = NULL;
388             ipDataPathLoggerIn = NULL;
389             ipDataPathLoggerOut = NULL;
390             ipClockLogger = NULL;
391             ipClockLoggerSessionDuration = NULL;
392             ipDiagnosticsLogger = NULL;
393             ipDataPathLoggerFlowCtrl = NULL;
394             if (IsAdded())
395             {
396                 RemoveFromScheduler();
397             }
398             SetState(EPVMFNodeCreated);
399             status = PVMFSuccess;
400         }
401         break;
402 
403         default:
404             status = PVMFErrInvalidState;
405             break;
406     }
407     return status;
408 }
409 
410 ///////////////////////////////////////////////////////////////////////////////
411 //Retrieves node capabilities.
412 //Decides supported input/output formats and provides node capabilities
413 //Return values: PVMFSuccess/PVMFErrInvalidState
414 //PVMFSuccess: If API call is successful
415 //If Input/Output format could not be determined
416 //Leave Codes: NA
417 ///////////////////////////////////////////////////////////////////////////////
GetCapability(PVMFNodeCapability & aNodeCapability)418 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferNode::GetCapability(PVMFNodeCapability& aNodeCapability)
419 {
420     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::GetCapability In"));
421     aNodeCapability = iCapability;
422     return PVMFSuccess;
423 }
424 
425 ///////////////////////////////////////////////////////////////////////////////
426 //Retrives a port iterator.
427 //Can Leave:No
428 //Return values: PVMFSuccess/PVMFErrInvalidState
429 //PVMFSuccess - If API call is successful
430 ////////////////////////////////////////////////////////////////////////////////
GetPorts(const PVMFPortFilter * aFilter)431 OSCL_EXPORT_REF PVMFPortIter* PVMFJitterBufferNode::GetPorts(const PVMFPortFilter* aFilter)
432 {
433     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::GetPorts"));
434     OSCL_UNUSED_ARG(aFilter);//port filter is not implemented.
435     iPortVector.Reset();
436     return &iPortVector;
437 }
438 
439 ///////////////////////////////////////////////////////////////////////////////
440 //Retrives a port iterator.
441 //Can Leave:No
442 //Return values: PVMFSuccess/PVMFErrInvalidState
443 //PVMFSuccess - If API call is successful
444 //PVMFErrInvalidState - If API is called in the invalid state
445 ////////////////////////////////////////////////////////////////////////////////
QueryUUID(PVMFSessionId s,const PvmfMimeString & aMimeType,Oscl_Vector<PVUuid,OsclMemAllocator> & aUuids,bool aExactUuidsOnly,const OsclAny * aContext)446 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::QueryUUID(PVMFSessionId s,
447         const PvmfMimeString& aMimeType,
448         Oscl_Vector< PVUuid, OsclMemAllocator >& aUuids,
449         bool aExactUuidsOnly ,
450         const OsclAny* aContext)
451 {
452     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::QueryUUID"));
453     PVMFJitterBufferNodeCommand cmd;
454     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
455             PVMF_JITTER_BUFFER_NODE_QUERYUUID,
456             aMimeType,
457             aUuids,
458             aExactUuidsOnly,
459             aContext);
460     return QueueCommandL(cmd);
461 }
462 
QueryInterface(PVMFSessionId s,const PVUuid & aUuid,PVInterface * & aInterfacePtr,const OsclAny * aContext)463 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::QueryInterface(PVMFSessionId s,
464         const PVUuid& aUuid,
465         PVInterface*& aInterfacePtr,
466         const OsclAny* aContext)
467 {
468     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:QueryInterface"));
469     PVMFJitterBufferNodeCommand cmd;
470     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
471             PVMF_JITTER_BUFFER_NODE_QUERYINTERFACE,
472             aUuid,
473             aInterfacePtr,
474             aContext);
475     return QueueCommandL(cmd);
476 }
477 
RequestPort(PVMFSessionId s,int32 aPortTag,const PvmfMimeString * aPortConfig,const OsclAny * aContext)478 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::RequestPort(PVMFSessionId s,
479         int32 aPortTag,
480         const PvmfMimeString* aPortConfig,
481         const OsclAny* aContext)
482 {
483     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:RequestPort"));
484     PVMFJitterBufferNodeCommand cmd;
485     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
486             PVMF_JITTER_BUFFER_NODE_REQUESTPORT,
487             aPortTag,
488             aPortConfig,
489             aContext);
490     return QueueCommandL(cmd);
491 }
492 
ReleasePort(PVMFSessionId s,PVMFPortInterface & aPort,const OsclAny * aContext)493 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::ReleasePort(PVMFSessionId s,
494         PVMFPortInterface& aPort,
495         const OsclAny* aContext)
496 {
497     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:ReleasePort"));
498     PVMFJitterBufferNodeCommand cmd;
499     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
500             PVMF_JITTER_BUFFER_NODE_RELEASEPORT,
501             aPort,
502             aContext);
503     return QueueCommandL(cmd);
504 }
505 
Init(PVMFSessionId s,const OsclAny * aContext)506 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Init(PVMFSessionId s,
507         const OsclAny* aContext)
508 {
509     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Init"));
510     PVMFJitterBufferNodeCommand cmd;
511     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
512             PVMF_JITTER_BUFFER_NODE_INIT,
513             aContext);
514     return QueueCommandL(cmd);
515 }
516 
Prepare(PVMFSessionId s,const OsclAny * aContext)517 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Prepare(PVMFSessionId s,
518         const OsclAny* aContext)
519 {
520     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Prepare"));
521     PVMFJitterBufferNodeCommand cmd;
522     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
523             PVMF_JITTER_BUFFER_NODE_PREPARE,
524             aContext);
525     return QueueCommandL(cmd);
526 }
527 
Start(PVMFSessionId s,const OsclAny * aContext)528 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Start(PVMFSessionId s,
529         const OsclAny* aContext)
530 {
531     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Start"));
532     PVMFJitterBufferNodeCommand cmd;
533     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
534             PVMF_JITTER_BUFFER_NODE_START,
535             aContext);
536     return QueueCommandL(cmd);
537 }
538 
Stop(PVMFSessionId s,const OsclAny * aContext)539 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Stop(PVMFSessionId s,
540         const OsclAny* aContext)
541 {
542     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Stop"));
543     PVMFJitterBufferNodeCommand cmd;
544     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
545             PVMF_JITTER_BUFFER_NODE_STOP,
546             aContext);
547     return QueueCommandL(cmd);
548 }
549 
Flush(PVMFSessionId s,const OsclAny * aContext)550 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Flush(PVMFSessionId s,
551         const OsclAny* aContext)
552 {
553     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Flush"));
554     PVMFJitterBufferNodeCommand cmd;
555     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
556             PVMF_JITTER_BUFFER_NODE_FLUSH,
557             aContext);
558     return QueueCommandL(cmd);
559 }
560 
Pause(PVMFSessionId s,const OsclAny * aContext)561 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Pause(PVMFSessionId s,
562         const OsclAny* aContext)
563 {
564     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Pause"));
565     PVMFJitterBufferNodeCommand cmd;
566     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
567             PVMF_JITTER_BUFFER_NODE_PAUSE,
568             aContext);
569     return QueueCommandL(cmd);
570 }
571 
Reset(PVMFSessionId s,const OsclAny * aContext)572 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::Reset(PVMFSessionId s,
573         const OsclAny* aContext)
574 {
575     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:Reset"));
576     PVMFJitterBufferNodeCommand cmd;
577     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
578             PVMF_JITTER_BUFFER_NODE_RESET,
579             aContext);
580     return QueueCommandL(cmd);
581 }
582 
CancelAllCommands(PVMFSessionId s,const OsclAny * aContextData)583 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::CancelAllCommands(PVMFSessionId s,
584         const OsclAny* aContextData)
585 {
586     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:CancelAllCommands"));
587     PVMFJitterBufferNodeCommand cmd;
588     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
589             PVMF_JITTER_BUFFER_NODE_CANCELALLCOMMANDS,
590             aContextData);
591     return QueueCommandL(cmd);
592 }
593 
CancelCommand(PVMFSessionId s,PVMFCommandId aCmdId,const OsclAny * aContextData)594 OSCL_EXPORT_REF PVMFCommandId PVMFJitterBufferNode::CancelCommand(PVMFSessionId s,
595         PVMFCommandId aCmdId,
596         const OsclAny* aContextData)
597 {
598     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:CancelCommand"));
599     PVMFJitterBufferNodeCommand cmd;
600     cmd.PVMFJitterBufferNodeCommandBase::Construct(s,
601             PVMF_JITTER_BUFFER_NODE_CANCELCOMMAND,
602             aCmdId,
603             aContextData);
604     return QueueCommandL(cmd);
605 }
606 
HandlePortActivity(const PVMFPortActivity & aActivity)607 void PVMFJitterBufferNode::HandlePortActivity(const PVMFPortActivity& aActivity)
608 {
609     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::PortActivity: port=0x%x, type=%d",
610                          aActivity.iPort, aActivity.iType));
611 
612     PVMFJitterBufferPortParams* portParamsPtr = NULL;
613     PVMFJitterBufferPort* jbPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aActivity.iPort);
614     portParamsPtr = jbPort->iPortParams;
615 
616     if (aActivity.iType != PVMF_PORT_ACTIVITY_DELETED)
617     {
618         if (portParamsPtr == NULL)
619         {
620             ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
621             PVMF_JBNODE_LOGERROR((0, "0x%x PVMFJitterBufferNode::HandlePortActivity - getPortContainer Failed", this));
622             return;
623         }
624     }
625 
626     /*
627      * A port is reporting some activity or state change.  This code
628      * figures out whether we need to queue a processing event
629      * for the AO, and/or report a node event to the observer.
630      */
631 
632     switch (aActivity.iType)
633     {
634         case PVMF_PORT_ACTIVITY_CREATED:
635             /*
636              * Report port created info event to the node.
637              */
638             ReportInfoEvent(PVMFInfoPortCreated, (OsclAny*)aActivity.iPort);
639             break;
640 
641         case PVMF_PORT_ACTIVITY_DELETED:
642             /*
643              * Report port deleted info event to the node.
644              */
645             ReportInfoEvent(PVMFInfoPortDeleted, (OsclAny*)aActivity.iPort);
646             break;
647 
648         case PVMF_PORT_ACTIVITY_CONNECT:
649             //nothing needed.
650             break;
651 
652         case PVMF_PORT_ACTIVITY_DISCONNECT:
653         {
654             if (ipJitterBufferMisc)
655             {
656                 LogSessionDiagnostics();
657                 ipJitterBufferMisc->StreamingSessionStopped();
658             }
659         }
660         break;
661 
662         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
663         {
664             if (portParamsPtr->iProcessOutgoingMessages)
665             {
666                 /*
667                  * An outgoing message was queued on this port.
668                  * All ports have outgoing messages
669                  * in this node
670                  */
671                 QueuePortActivity(portParamsPtr, aActivity);
672             }
673         }
674         break;
675 
676         case PVMF_PORT_ACTIVITY_INCOMING_MSG:
677         {
678             /*
679              * An outgoing message was queued on this port.
680              * Only input and feedback ports have incoming messages
681              * in this node
682              */
683             int32 portTag = portParamsPtr->iTag;
684             switch (portTag)
685             {
686                 case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
687                 case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
688                     if (portParamsPtr->iProcessIncomingMessages)
689                     {
690                         QueuePortActivity(portParamsPtr, aActivity);
691                     }
692                     break;
693 
694                 default:
695                     OSCL_ASSERT(false);
696                     break;
697             }
698         }
699         break;
700 
701         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
702         {
703             int32 portTag = portParamsPtr->iTag;
704             switch (portTag)
705             {
706                 case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
707                     /*
708                      * We typically use incoming port's outgoing q
709                      * only in case of 3GPP streaming, wherein we
710                      * send firewall packets. If it is busy, it does
711                      * not stop us from registering incoming data pkts.
712                      * so do nothing.
713                      */
714                     break;
715 
716                 case PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT:
717                 {
718                     /*
719                      * This implies that this output port cannot accept any more
720                      * msgs on its outgoing queue. This would usually imply that
721                      * the corresponding input port must stop processing messages,
722                      * however in case of jitter buffer the input and output ports
723                      * are separated by a huge jitter buffer. Therefore continue
724                      * to process the input.
725                      */
726                 }
727                 break;
728 
729                 case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
730                     portParamsPtr->iProcessIncomingMessages = false;
731                     break;
732 
733                 default:
734                     OSCL_ASSERT(false);
735                     break;
736             }
737         }
738         break;
739 
740         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
741         {
742             int32 portTag = portParamsPtr->iTag;
743             /*
744              * Outgoing queue was previously busy, but is now ready.
745              * We may need to schedule new processing events depending
746              * on the port type.
747              */
748             switch (portTag)
749             {
750                 case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
751                     /*
752                      * We never did anything in PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY
753                      * so do nothing
754                      */
755                     break;
756 
757                 case PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT:
758                 {
759                     /*
760                      * This implies that this output port can accept more
761                      * msgs on its outgoing queue. This implies that the corresponding
762                      * input port can start processing messages again.
763                      */
764                     PVMFJitterBufferPort* jbPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aActivity.iPort);
765                     PVMFJitterBufferPortParams* inPortParams = jbPort->iCounterpartPortParams;
766                     if (inPortParams != NULL)
767                     {
768                         inPortParams->iProcessIncomingMessages = true;
769                     }
770                     else
771                     {
772                         OSCL_ASSERT(false);
773                     }
774                 }
775                 break;
776 
777                 case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
778                     portParamsPtr->iProcessIncomingMessages = true;
779                     break;
780 
781                 default:
782                     OSCL_ASSERT(false);
783                     break;
784             }
785             if (IsAdded())
786             {
787                 RunIfNotReady();
788             }
789         }
790         break;
791 
792         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
793         {
794             /*
795              * The connected port has become busy (its incoming queue is
796              * busy).
797              */
798             int32 portTag = portParamsPtr->iTag;
799             switch (portTag)
800             {
801                 case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
802                     break;
803 
804                 case PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT:
805                 {
806                     /*
807                      * This implies that this output port cannot send any more
808                      * msgs from its outgoing queue. It should stop processing
809                      * messages till the connect port is ready.
810                      */
811                     portParamsPtr->iProcessOutgoingMessages = false;
812                 }
813                 break;
814 
815                 case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
816                     portParamsPtr->iProcessOutgoingMessages = false;
817                     break;
818 
819                 default:
820                     OSCL_ASSERT(false);
821                     break;
822             }
823         }
824         break;
825 
826         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
827         {
828             /*
829              * The connected port has transitioned from Busy to Ready.
830              * It's time to start processing messages outgoing again.
831              */
832             int32 portTag = portParamsPtr->iTag;
833             switch (portTag)
834             {
835                 case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
836                     break;
837 
838                 case PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT:
839                     /*
840                      * This implies that this output port can now send
841                      * msgs from its outgoing queue. It can start processing
842                      * messages now.
843                      */
844                     portParamsPtr->iProcessOutgoingMessages = true;
845                     break;
846 
847                 case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
848                     portParamsPtr->iProcessOutgoingMessages = true;
849                     break;
850 
851                 default:
852                     OSCL_ASSERT(false);
853                     break;
854             }
855             if (IsAdded())
856             {
857                 RunIfNotReady();
858             }
859         }
860         break;
861 
862         default:
863             break;
864     }
865 }
866 
867 /////////////////////////////////////////////////////
868 // Port Processing routines
869 /////////////////////////////////////////////////////
QueuePortActivity(PVMFJitterBufferPortParams * aPortParams,const PVMFPortActivity & aActivity)870 void PVMFJitterBufferNode::QueuePortActivity(PVMFJitterBufferPortParams* aPortParams,
871         const PVMFPortActivity &aActivity)
872 {
873     OSCL_UNUSED_ARG(aPortParams);
874     OSCL_UNUSED_ARG(aActivity);
875 
876     if (IsAdded())
877     {
878         /*
879          * wake up the AO to process the port activity event.
880          */
881         RunIfNotReady();
882     }
883 }
884 
885 ///////////////////////////////////////////////////////////////////////////////
886 //Extension interfaces function implementation
887 ///////////////////////////////////////////////////////////////////////////////
SetRTCPIntervalInMicroSecs(uint32 aRTCPInterval)888 void PVMFJitterBufferNode::SetRTCPIntervalInMicroSecs(uint32 aRTCPInterval)
889 {
890     OSCL_UNUSED_ARG(aRTCPInterval);
891 }
892 
SetPortParams(PVMFPortInterface * aPort,uint32 aTimeScale,uint32 aBitRate,OsclRefCounterMemFrag & aConfig,bool aRateAdaptation,uint32 aRateAdaptationFeedBackFrequency)893 bool PVMFJitterBufferNode::SetPortParams(PVMFPortInterface* aPort,
894         uint32 aTimeScale,
895         uint32 aBitRate,
896         OsclRefCounterMemFrag& aConfig,
897         bool aRateAdaptation,
898         uint32 aRateAdaptationFeedBackFrequency)
899 {
900     return SetPortParams(aPort, aTimeScale, aBitRate, aConfig, aRateAdaptation,
901                          aRateAdaptationFeedBackFrequency, false);
902 }
903 
SetPlayRange(int32 aStartTimeInMS,int32 aStopTimeInMS,bool aPlayAfterASeek,bool aStopTimeAvailable)904 bool PVMFJitterBufferNode::SetPlayRange(int32 aStartTimeInMS,
905                                         int32 aStopTimeInMS,
906                                         bool aPlayAfterASeek,
907                                         bool aStopTimeAvailable)
908 {
909     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetPlayRange In StartTime[%d], StopTime[%d] StopTimeValid[%d] PlayingAfterSeek[%d]", aStartTimeInMS, aStopTimeInMS, aStopTimeAvailable, aPlayAfterASeek));
910     ipJitterBufferMisc->SetPlayRange(aStartTimeInMS, aStopTimeInMS, aPlayAfterASeek, aStopTimeAvailable);
911     return true;
912 }
913 
SetPlayBackThresholdInMilliSeconds(uint32 aThreshold)914 void PVMFJitterBufferNode::SetPlayBackThresholdInMilliSeconds(uint32 aThreshold)
915 {
916     OSCL_UNUSED_ARG(aThreshold);
917 }
918 
SetJitterBufferRebufferingThresholdInMilliSeconds(uint32 aThreshold)919 void PVMFJitterBufferNode::SetJitterBufferRebufferingThresholdInMilliSeconds(uint32 aThreshold)
920 {
921     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetJitterBufferRebufferingThresholdInMilliSeconds Threshhold[%d]", aThreshold));
922     if (aThreshold < iJitterBufferDurationInMilliSeconds)
923     {
924         iRebufferingThreshold = aThreshold;
925         Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
926         for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
927         {
928             PVMFJitterBufferPortParams* pPortParams = *it;
929             if ((pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT))
930             {
931                 PVMFJitterBuffer* jitterBuffer = pPortParams->ipJitterBuffer;
932                 if (jitterBuffer)
933                 {
934                     jitterBuffer->SetRebufferingThresholdInMilliSeconds(aThreshold);
935                 }
936             }
937         }
938     }
939 }
940 
GetJitterBufferRebufferingThresholdInMilliSeconds(uint32 & aThreshold)941 void PVMFJitterBufferNode::GetJitterBufferRebufferingThresholdInMilliSeconds(uint32& aThreshold)
942 {
943     aThreshold = iRebufferingThreshold;
944 }
945 
SetJitterBufferDurationInMilliSeconds(uint32 aDuration)946 void PVMFJitterBufferNode::SetJitterBufferDurationInMilliSeconds(uint32 aDuration)
947 {
948     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetJitterBufferDurationInMilliSeconds Duration [%d]", aDuration));
949     uint32 duration = iJitterBufferDurationInMilliSeconds;
950     if (aDuration > iRebufferingThreshold)
951     {
952         duration = aDuration;
953         iJitterBufferDurationInMilliSeconds = duration;
954     }
955 
956     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
957     for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
958     {
959         PVMFJitterBufferPortParams* pPortParams  = *it;
960         if ((pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT))
961         {
962             PVMFJitterBuffer* jitterBuffer = pPortParams->ipJitterBuffer;
963             if (jitterBuffer)
964             {
965                 jitterBuffer->SetDurationInMilliSeconds(duration);
966             }
967         }
968     }
969 }
970 
GetJitterBufferDurationInMilliSeconds(uint32 & duration)971 void PVMFJitterBufferNode::GetJitterBufferDurationInMilliSeconds(uint32& duration)
972 {
973     duration = iJitterBufferDurationInMilliSeconds;
974 }
975 
SetEarlyDecodingTimeInMilliSeconds(uint32 duration)976 void PVMFJitterBufferNode::SetEarlyDecodingTimeInMilliSeconds(uint32 duration)
977 {
978     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetEarlyDecodingTimeInMilliSeconds - Early Decoding Time [%d]", duration));
979     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
980     for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end(); iter++)
981     {
982         PVMFJitterBufferPortParams* pPortParams = *iter;
983         if (pPortParams && (pPortParams->ipJitterBuffer) && (PVMF_JITTER_BUFFER_PORT_TYPE_INPUT == pPortParams->iTag))
984         {
985             pPortParams->ipJitterBuffer->SetEarlyDecodingTimeInMilliSeconds(duration);
986         }
987     }
988 }
989 
SetBurstThreshold(float burstThreshold)990 void PVMFJitterBufferNode::SetBurstThreshold(float burstThreshold)
991 {
992     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetBurstThreshold burstThreshold[%f]", burstThreshold));
993     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
994     for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end(); iter++)
995     {
996         PVMFJitterBufferPortParams* pPortParams = *iter;
997         if (pPortParams && (pPortParams->ipJitterBuffer) && (PVMF_JITTER_BUFFER_PORT_TYPE_INPUT == pPortParams->iTag))
998         {
999             pPortParams->ipJitterBuffer->SetBurstThreshold(burstThreshold);
1000         }
1001     }
1002 }
1003 
SetMaxInactivityDurationForMediaInMs(uint32 aDuration)1004 void PVMFJitterBufferNode::SetMaxInactivityDurationForMediaInMs(uint32 aDuration)
1005 {
1006     iMaxInactivityDurationForMediaInMs = aDuration;
1007 }
1008 
GetMaxInactivityDurationForMediaInMs(uint32 & aDuration)1009 void PVMFJitterBufferNode::GetMaxInactivityDurationForMediaInMs(uint32& aDuration)
1010 {
1011     aDuration = iMaxInactivityDurationForMediaInMs;
1012 }
1013 
SetClientPlayBackClock(PVMFMediaClock * aClientClock)1014 void PVMFJitterBufferNode::SetClientPlayBackClock(PVMFMediaClock* aClientClock)
1015 {
1016     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetClientPlayBackClock %x", aClientClock));
1017     //remove ourself as observer of old clock, if any.
1018     //Todo: Repetition should make sence only after call to Reset function.
1019     ipClientPlayBackClock = aClientClock;
1020 }
1021 
PrepareForRepositioning(bool oUseExpectedClientClockVal,uint32 aExpectedClientClockVal)1022 bool PVMFJitterBufferNode::PrepareForRepositioning(bool oUseExpectedClientClockVal ,
1023         uint32 aExpectedClientClockVal)
1024 {
1025     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::PrepareForRepositioning oUseExpectedClientClockVal[%d], aExpectedClientClockVal[%d]", oUseExpectedClientClockVal, aExpectedClientClockVal));
1026     iJitterBufferState = PVMF_JITTER_BUFFER_IN_TRANSITION;
1027     ipJitterBufferMisc->PrepareForRepositioning(oUseExpectedClientClockVal, aExpectedClientClockVal);
1028     return true;
1029 }
1030 
SetPortSSRC(PVMFPortInterface * aPort,uint32 aSSRC)1031 bool PVMFJitterBufferNode::SetPortSSRC(PVMFPortInterface* aPort, uint32 aSSRC)
1032 {
1033     bool retval = false;
1034     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetPortSSRC aPort[%x], aSSRC[%d]", aPort, aSSRC));
1035     if(aPort)
1036     {
1037         Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::const_iterator iter;
1038         for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end() ; ++iter)
1039         {
1040             if (iter && (*iter) && (&((*iter)->irPort) == aPort))
1041             {
1042                 retval = true;
1043                 ipJitterBufferMisc->SetPortSSRC(aPort, aSSRC);
1044                 break;
1045             }
1046         }
1047     }
1048     return retval;
1049 }
1050 
SetPortRTPParams(PVMFPortInterface * aPort,bool aSeqNumBasePresent,uint32 aSeqNumBase,bool aRTPTimeBasePresent,uint32 aRTPTimeBase,bool aNPTTimeBasePresent,uint32 aNPTInMS,bool oPlayAfterASeek)1051 bool PVMFJitterBufferNode::SetPortRTPParams(PVMFPortInterface* aPort,
1052         bool   aSeqNumBasePresent,
1053         uint32 aSeqNumBase,
1054         bool   aRTPTimeBasePresent,
1055         uint32 aRTPTimeBase,
1056         bool   aNPTTimeBasePresent,
1057         uint32 aNPTInMS,
1058         bool oPlayAfterASeek)
1059 {
1060     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetPortRTPParams In Port - 0x%x", aPort));
1061     uint32 i;
1062     //The above method is called only during 3GPP repositioning, however, since the aPort param in the signature
1063     // takes care only of the input port, the output port msg queues aren't cleared.
1064     // As a result ClearMsgQueues need to be called explicity on all the ports.
1065     //The oPlayAfterASeek check is necessary since the clearing of msg queues has to be carried out only during repositioning,
1066     // not otherwise
1067     if (oPlayAfterASeek)
1068     {
1069         for (i = 0; i < iPortParamsQueue.size(); i++)
1070         {
1071             PVMFJitterBufferPortParams* pPortParams = iPortParamsQueue[i];
1072             pPortParams->irPort.ClearMsgQueues();
1073         }
1074     }
1075     for (i = 0; i < iPortParamsQueue.size(); i++)
1076     {
1077         PVMFJitterBufferPortParams* pPortParams = iPortParamsQueue[i];
1078 
1079         if (&pPortParams->irPort == aPort)
1080         {
1081             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
1082             {
1083                 if (pPortParams->ipJitterBuffer != NULL)
1084                 {
1085                     PVMFRTPInfoParams rtpInfoParams;
1086                     rtpInfoParams.seqNumBaseSet = aSeqNumBasePresent;
1087                     rtpInfoParams.seqNum = aSeqNumBase;
1088                     rtpInfoParams.rtpTimeBaseSet = aRTPTimeBasePresent;
1089                     rtpInfoParams.rtpTime = aRTPTimeBase;
1090                     rtpInfoParams.nptTimeBaseSet = aNPTTimeBasePresent;
1091                     rtpInfoParams.nptTimeInMS = aNPTInMS;
1092                     rtpInfoParams.rtpTimeScale = pPortParams->iTimeScale;
1093                     pPortParams->ipJitterBuffer->setRTPInfoParams(rtpInfoParams, oPlayAfterASeek);
1094                     /* In case this is after a reposition purge the jitter buffer */
1095                     if (oPlayAfterASeek)
1096                     {
1097                         uint32 timebase32 = 0;
1098                         uint32 clientClock32 = 0;
1099                         bool overflowFlag = false;
1100                         if (ipClientPlayBackClock != NULL)
1101                             ipClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
1102 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
1103 
1104                         PVMF_JBNODE_LOGCLOCK_REBUFF((0, "PVMFJitterBufferNode::setPortRTPParams - Purging Upto SeqNum =%d", aSeqNumBase));
1105                         PVMF_JBNODE_LOGCLOCK_REBUFF((0, "PVMFJitterBufferNode::setPortRTPParams - Before Purge - ClientClock=%d",
1106                                                      clientClock32));
1107 #endif
1108                         pPortParams->ipJitterBuffer->PurgeElementsWithSeqNumsLessThan(aSeqNumBase,
1109                                 clientClock32);
1110 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
1111                         PVMF_JBNODE_LOGCLOCK_REBUFF((0, "PVMFJitterBufferNode::setPortRTPParams - After Purge - ClientClock=%d",
1112                                                      clientClock32));
1113 #endif
1114                         /*
1115                          * Since we flushed the jitter buffer, set it to ready state,
1116                          * reset the delay flag
1117                          */
1118                         iDelayEstablished = false;
1119                         iJitterBufferState = PVMF_JITTER_BUFFER_READY;
1120                         //iPlayingAfterSeek = true;
1121                     }
1122                 }
1123                 return true;
1124             }
1125         }
1126     }
1127     return false;
1128 }
1129 
SetPortRTCPParams(PVMFPortInterface * aPort,int aNumSenders,uint32 aRR,uint32 aRS)1130 bool PVMFJitterBufferNode::SetPortRTCPParams(PVMFPortInterface* aPort,
1131         int aNumSenders,
1132         uint32 aRR,
1133         uint32 aRS)
1134 {
1135     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetPortRTCPParams aPort - [0x%x]", aPort));
1136     return ipJitterBufferMisc->SetPortRTCPParams(aPort, aNumSenders, aRR, aRS);
1137 }
1138 
GetActualMediaDataTSAfterSeek()1139 PVMFTimestamp PVMFJitterBufferNode::GetActualMediaDataTSAfterSeek()
1140 {
1141     return ipJitterBufferMisc->GetActualMediaDataTSAfterSeek();
1142 }
1143 
GetMaxMediaDataTS()1144 PVMFTimestamp PVMFJitterBufferNode::GetMaxMediaDataTS()
1145 {
1146     return ipJitterBufferMisc->GetMaxMediaDataTS();
1147 }
1148 
SetServerInfo(PVMFJitterBufferFireWallPacketInfo & aServerInfo)1149 PVMFStatus PVMFJitterBufferNode::SetServerInfo(PVMFJitterBufferFireWallPacketInfo& aServerInfo)
1150 {
1151     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetServerInfo In"));
1152     if (iDisableFireWallPackets == false)
1153     {
1154         ipJitterBufferMisc->SetServerInfo(aServerInfo);
1155     }
1156     else
1157     {
1158         PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::setServerInfo: FW Pkts Disabled"));
1159         if (iCurrentCommand.size() > 0)
1160         {
1161             if (iCurrentCommand.front().iCmd == PVMF_JITTER_BUFFER_NODE_PREPARE)
1162             {
1163                 /* No firewall packet exchange - Complete Prepare */
1164                 CompletePrepare();
1165             }
1166         }
1167     }
1168     return PVMFSuccess;
1169 }
1170 
NotifyOutOfBandEOS()1171 PVMFStatus PVMFJitterBufferNode::NotifyOutOfBandEOS()
1172 {
1173     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS In"));
1174     // Ignore Out Of Band EOS for any Non Live stream
1175     if (ipJitterBufferMisc && (!ipJitterBufferMisc->PlayStopTimeAvailable()))
1176     {
1177         if (iJitterBufferState != PVMF_JITTER_BUFFER_IN_TRANSITION)
1178         {
1179             ipJitterBufferMisc->SetSessionDurationExpired();
1180             CancelEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
1181             PVMF_JBNODE_LOGDATATRAFFIC((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS - Out Of Band EOS Recvd"));
1182             PVMF_JBNODE_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS - Out Of Band EOS Recvd"));
1183         }
1184         else
1185         {
1186             PVMF_JBNODE_LOGDATATRAFFIC((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS - Ignoring Out Of Band EOS in Transition State"));
1187             PVMF_JBNODE_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS - Ignoring Out Of Band EOS in Transition State"));
1188         }
1189     }
1190     else
1191     {
1192         PVMF_JBNODE_LOGDATATRAFFIC((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS - Ignoring Out Of Band EOS for Non Live Stream"));
1193         PVMF_JBNODE_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::NotifyOutOfBandEOS - Ignoring Out Of Band EOS for Non Live Stream"));
1194     }
1195     return PVMFSuccess;
1196 }
1197 
SendBOSMessage(uint32 aStreamID)1198 PVMFStatus PVMFJitterBufferNode::SendBOSMessage(uint32 aStreamID)
1199 {
1200     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SendBOSMessage In"));
1201     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
1202     for (it = iPortParamsQueue.begin();
1203             it != iPortParamsQueue.end();
1204             it++)
1205     {
1206         PVMFJitterBufferPortParams* pPortParams = *it;
1207         if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
1208         {
1209             if (pPortParams->ipJitterBuffer)
1210             {
1211                 pPortParams->ipJitterBuffer->QueueBOSCommand(aStreamID);
1212             }
1213         }
1214     }
1215     PVMF_JBNODE_LOGDATATRAFFIC((0, "PVMFJitterBufferNode::SendBOSMessage - BOS Recvd"));
1216     return PVMFSuccess;
1217 }
1218 
SetJitterBufferChunkAllocator(OsclMemPoolResizableAllocator * aDataBufferAllocator,const PVMFPortInterface * aPort)1219 void PVMFJitterBufferNode::SetJitterBufferChunkAllocator(OsclMemPoolResizableAllocator*
1220         aDataBufferAllocator, const PVMFPortInterface* aPort)
1221 {
1222     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetJitterBufferChunkAllocator -aPort 0x%x", aPort));
1223     PVMFJitterBufferPort* port = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aPort);
1224     if (port->iPortParams->ipJitterBuffer)
1225     {
1226         port->iPortParams->ipJitterBuffer->SetJitterBufferChunkAllocator(aDataBufferAllocator);
1227     }
1228 }
1229 
SetJitterBufferMemPoolInfo(const PvmfPortBaseImpl * aPort,uint32 aSize,uint32 aResizeSize,uint32 aMaxNumResizes,uint32 aExpectedNumberOfBlocksPerBuffer)1230 void PVMFJitterBufferNode::SetJitterBufferMemPoolInfo(const PvmfPortBaseImpl* aPort,
1231         uint32 aSize,
1232         uint32 aResizeSize,
1233         uint32 aMaxNumResizes,
1234         uint32 aExpectedNumberOfBlocksPerBuffer)
1235 {
1236     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetJitterBufferMemPoolInfo Port 0x%x", aPort));
1237     PVMFJitterBufferPort* port = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aPort);
1238     if (port->iPortParams->ipJitterBuffer)
1239     {
1240         port->iPortParams->ipJitterBuffer->SetJitterBufferMemPoolInfo(aSize, aResizeSize, aMaxNumResizes, aExpectedNumberOfBlocksPerBuffer);
1241     }
1242 }
1243 
GetJitterBufferMemPoolInfo(const PvmfPortBaseImpl * aPort,uint32 & aSize,uint32 & aResizeSize,uint32 & aMaxNumResizes,uint32 & aExpectedNumberOfBlocksPerBuffer) const1244 void PVMFJitterBufferNode::GetJitterBufferMemPoolInfo(const PvmfPortBaseImpl* aPort,
1245         uint32& aSize,
1246         uint32& aResizeSize,
1247         uint32& aMaxNumResizes,
1248         uint32& aExpectedNumberOfBlocksPerBuffer) const
1249 {
1250     PVMFJitterBufferPort* port = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aPort);
1251     if (port->iPortParams->ipJitterBuffer)
1252     {
1253         port->iPortParams->ipJitterBuffer->GetJitterBufferMemPoolInfo(aSize, aResizeSize, aMaxNumResizes, aExpectedNumberOfBlocksPerBuffer);
1254     }
1255 }
1256 
SetSharedBufferResizeParams(uint32 maxNumResizes,uint32 resizeSize)1257 void PVMFJitterBufferNode::SetSharedBufferResizeParams(uint32 maxNumResizes,
1258         uint32 resizeSize)
1259 {
1260     // make sure we're in a state that makes sense
1261     OSCL_ASSERT((iInterfaceState == EPVMFNodeCreated) ||
1262                 (iInterfaceState == EPVMFNodeIdle) ||
1263                 (iInterfaceState == EPVMFNodeInitialized));
1264 
1265     iMaxNumBufferResizes = maxNumResizes;
1266     iBufferResizeSize = resizeSize;
1267 }
1268 
GetSharedBufferResizeParams(uint32 & maxNumResizes,uint32 & resizeSize)1269 void PVMFJitterBufferNode::GetSharedBufferResizeParams(uint32& maxNumResizes,
1270         uint32& resizeSize)
1271 {
1272     maxNumResizes = iMaxNumBufferResizes;
1273     resizeSize = iBufferResizeSize;
1274 }
1275 
ClearJitterBuffer(PVMFPortInterface * aPort,uint32 aSeqNum)1276 bool PVMFJitterBufferNode::ClearJitterBuffer(PVMFPortInterface* aPort,
1277         uint32 aSeqNum)
1278 {
1279     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ClearJitterBuffer Port 0x%x aSeqNum[%d]", aPort, aSeqNum));
1280     /* Typically called only for HTTP streaming sessions */
1281     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
1282     for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
1283     {
1284         PVMFJitterBufferPortParams* pPortParams = *it;
1285         pPortParams->irPort.ClearMsgQueues();
1286     }
1287 
1288     for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
1289     {
1290         PVMFJitterBufferPortParams* pPortParams = *it;
1291         if (&pPortParams->irPort == aPort && (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT) && (pPortParams->ipJitterBuffer != NULL))
1292         {
1293             uint32 timebase32 = 0;
1294             uint32 clientClock32 = 0;
1295             bool overflowFlag = false;
1296             if (ipClientPlayBackClock != NULL)
1297                 ipClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
1298             pPortParams->ipJitterBuffer->PurgeElementsWithSeqNumsLessThan(aSeqNum,
1299                     clientClock32);
1300             ipJitterBufferMisc->ResetSession();
1301             iJitterBufferState = PVMF_JITTER_BUFFER_READY;
1302             return true;
1303         }
1304     }
1305     return false;
1306 }
1307 
FlushJitterBuffer()1308 void PVMFJitterBufferNode::FlushJitterBuffer()
1309 {
1310     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::FlushJitterBuffer In"));
1311     for (uint32 i = 0; i < iPortParamsQueue.size(); i++)
1312     {
1313         PVMFJitterBufferPortParams* pPortParams = iPortParamsQueue[i];
1314         if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
1315         {
1316             if (pPortParams->ipJitterBuffer != NULL)
1317             {
1318                 pPortParams->ipJitterBuffer->FlushJitterBuffer();
1319             }
1320         }
1321     }
1322 }
1323 
SetInputMediaHeaderPreParsed(PVMFPortInterface * aPort,bool aHeaderPreParsed)1324 PVMFStatus PVMFJitterBufferNode::SetInputMediaHeaderPreParsed(PVMFPortInterface* aPort,
1325         bool aHeaderPreParsed)
1326 {
1327     PVMFStatus status = PVMFFailure;
1328     PVMFJitterBufferPort *port = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aPort);
1329     if (port)
1330     {
1331         PVMFJitterBufferPortParams* portParams = port->GetPortParams();
1332         if (portParams && portParams->ipJitterBuffer)
1333         {
1334             status = portParams->ipJitterBuffer->SetInputPacketHeaderPreparsed(aHeaderPreParsed);
1335         }
1336     }
1337     return status;
1338 }
1339 
HasSessionDurationExpired(bool & aExpired)1340 PVMFStatus PVMFJitterBufferNode::HasSessionDurationExpired(bool& aExpired)
1341 {
1342     aExpired = ipJitterBufferMisc->IsSessionExpired();
1343     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::HasSessionDurationExpired %d", aExpired));
1344     return PVMFSuccess;
1345 }
1346 
PurgeElementsWithNPTLessThan(NptTimeFormat & aNPTTime)1347 bool PVMFJitterBufferNode::PurgeElementsWithNPTLessThan(NptTimeFormat &aNPTTime)
1348 {
1349     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::PurgeElementsWithNPTLessThan"));
1350     bool retval = false;
1351 
1352     if (ipJitterBufferMisc)
1353     {
1354         retval = ipJitterBufferMisc->PurgeElementsWithNPTLessThan(aNPTTime);
1355     }
1356 
1357     iJitterBufferState = PVMF_JITTER_BUFFER_READY;
1358 
1359     return retval;
1360 }
1361 
SetBroadCastSession()1362 void PVMFJitterBufferNode::SetBroadCastSession()
1363 {
1364     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetBroadCastSession"));
1365     iBroadCastSession = true;
1366     if (ipJitterBufferMisc)
1367     {
1368         ipJitterBufferMisc->SetBroadcastSession();
1369     }
1370 }
1371 
DisableFireWallPackets()1372 void PVMFJitterBufferNode::DisableFireWallPackets()
1373 {
1374     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DisableFireWallPackets"));
1375     if (ipJitterBufferMisc)
1376         ipJitterBufferMisc->MediaReceivingChannelPreparationRequired(false);
1377 }
1378 
UpdateJitterBufferState()1379 void PVMFJitterBufferNode::UpdateJitterBufferState()
1380 {
1381     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::UpdateJitterBufferState"));
1382     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
1383     for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end(); iter ++)
1384     {
1385         PVMFJitterBufferPortParams* ptr = *iter;
1386         if (PVMF_JITTER_BUFFER_PORT_TYPE_INPUT == ptr->iTag)
1387         {
1388             ptr->ipJitterBuffer->SetJitterBufferState(PVMF_JITTER_BUFFER_READY);
1389         }
1390     }
1391     iDelayEstablished = true;
1392 }
1393 
StartOutputPorts()1394 void PVMFJitterBufferNode::StartOutputPorts()
1395 {
1396     oStopOutputPorts = false;
1397 }
1398 
StopOutputPorts()1399 void PVMFJitterBufferNode::StopOutputPorts()
1400 {
1401     oStopOutputPorts = true;
1402 }
1403 
1404 ///////////////////////////////////////////////////////////////////////////////
1405 //Used for the implementation of extension interface functions
1406 ///////////////////////////////////////////////////////////////////////////////
1407 bool
SetPortParams(PVMFPortInterface * aPort,uint32 aTimeScale,uint32 aBitRate,OsclRefCounterMemFrag & aConfig,bool aRateAdaptation,uint32 aRateAdaptationFeedBackFrequency,uint aMaxNumBuffResizes,uint aBuffResizeSize)1408 PVMFJitterBufferNode::SetPortParams(PVMFPortInterface* aPort,
1409                                     uint32 aTimeScale,
1410                                     uint32 aBitRate,
1411                                     OsclRefCounterMemFrag& aConfig,
1412                                     bool aRateAdaptation,
1413                                     uint32 aRateAdaptationFeedBackFrequency,
1414                                     uint aMaxNumBuffResizes, uint aBuffResizeSize)
1415 {
1416     return SetPortParams(aPort, aTimeScale, aBitRate, aConfig, aRateAdaptation,
1417                          aRateAdaptationFeedBackFrequency, true,
1418                          aMaxNumBuffResizes, aBuffResizeSize);
1419 }
1420 bool
SetPortParams(PVMFPortInterface * aPort,uint32 aTimeScale,uint32 aBitRate,OsclRefCounterMemFrag & aConfig,bool aRateAdaptation,uint32 aRateAdaptationFeedBackFrequency,bool aUserSpecifiedBuffParams,uint aMaxNumBuffResizes,uint aBuffResizeSize)1421 PVMFJitterBufferNode::SetPortParams(PVMFPortInterface* aPort,
1422                                     uint32 aTimeScale,
1423                                     uint32 aBitRate,
1424                                     OsclRefCounterMemFrag& aConfig,
1425                                     bool aRateAdaptation,
1426                                     uint32 aRateAdaptationFeedBackFrequency,
1427                                     bool aUserSpecifiedBuffParams,
1428                                     uint aMaxNumBuffResizes, uint aBuffResizeSize)
1429 {
1430     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::SetPortParams"));
1431     OSCL_UNUSED_ARG(aUserSpecifiedBuffParams);
1432     uint32 ii;
1433     for (ii = 0; ii < iPortParamsQueue.size(); ii++)
1434     {
1435         PVMFJitterBufferPortParams* pPortParams = iPortParamsQueue[ii];
1436 
1437         if (&pPortParams->irPort == aPort)
1438         {
1439             pPortParams->iTimeScale = aTimeScale;
1440             pPortParams->iMediaClockConverter.set_timescale(aTimeScale);
1441             pPortParams->iBitrate = aBitRate;
1442             if (pPortParams->ipJitterBuffer)
1443             {
1444                 pPortParams->ipJitterBuffer->SetTrackConfig(aConfig);
1445                 pPortParams->ipJitterBuffer->SetTimeScale(aTimeScale);
1446                 pPortParams->ipJitterBuffer->SetMediaClockConverter(&pPortParams->iMediaClockConverter);
1447             }
1448 
1449 
1450             /* Compute buffer size based on bitrate and jitter duration*/
1451             uint32 sizeInBytes = 0;
1452             if (((int32)iJitterBufferDurationInMilliSeconds > 0) &&
1453                     ((int32)aBitRate > 0))
1454             {
1455                 uint32 byteRate = aBitRate / 8;
1456                 uint32 overhead = (byteRate * PVMF_JITTER_BUFFER_NODE_MEM_POOL_OVERHEAD) / 100;
1457                 uint32 durationInSec = iJitterBufferDurationInMilliSeconds / 1000;
1458                 sizeInBytes = ((byteRate + overhead) * durationInSec);
1459                 if (sizeInBytes < MIN_RTP_SOCKET_MEM_POOL_SIZE_IN_BYTES)
1460                 {
1461                     sizeInBytes = MIN_RTP_SOCKET_MEM_POOL_SIZE_IN_BYTES;
1462                 }
1463                 sizeInBytes += (2 * MAX_SOCKET_BUFFER_SIZE);
1464             }
1465 
1466             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
1467             {
1468                 PVMFJitterBuffer* jitterBuffer = NULL;
1469                 jitterBuffer = pPortParams->ipJitterBuffer;
1470 
1471                 if (jitterBuffer)
1472                 {
1473                     pPortParams->ipJitterBuffer->SetJitterBufferMemPoolInfo(sizeInBytes, aBuffResizeSize, aMaxNumBuffResizes, 3000);
1474                 }
1475 
1476                 if (ipJitterBufferMisc)
1477                     ipJitterBufferMisc->SetRateAdaptationInfo(&pPortParams->irPort, aRateAdaptation, aRateAdaptationFeedBackFrequency, sizeInBytes);
1478             }
1479 
1480             iPortParamsQueue[ii] = pPortParams;
1481             return true;
1482         }
1483     }
1484     return false;
1485 }
1486 
1487 // This routine is called by various command APIs to queue an
1488 // asynchronous command for processing by the command handler AO.
1489 // This function may leave if the command can't be queued due to
1490 // memory allocation failure.
QueueCommandL(PVMFJitterBufferNodeCommand & aCmd)1491 PVMFCommandId PVMFJitterBufferNode::QueueCommandL(PVMFJitterBufferNodeCommand& aCmd)
1492 {
1493     PVMFCommandId id;
1494 
1495     id = iInputCommands.AddL(aCmd);
1496 
1497     if (IsAdded())
1498     {
1499         //wakeup the AO
1500         RunIfNotReady();
1501     }
1502     return id;
1503 }
1504 
1505 ///////////////////////////////////////////////////////////////////////////////
1506 //OsclActiveObject Implementation
1507 ///////////////////////////////////////////////////////////////////////////////
1508 /**
1509  * This AO handles both API commands and port activity.
1510  * The AO will either process one command or service one connected
1511  * port per call.  It will re-schedule itself and run continuously
1512  * until it runs out of things to do.
1513  */
Run()1514 void PVMFJitterBufferNode::Run()
1515 {
1516     iNumRunL++;
1517     /*
1518      * Process commands.
1519      */
1520     if (!iInputCommands.empty())
1521     {
1522         if (ProcessCommand(iInputCommands.front()))
1523         {
1524             /*
1525              * note: need to check the state before re-scheduling
1526              * since the node could have been reset in the ProcessCommand
1527              * call.
1528              */
1529             if (iInterfaceState != EPVMFNodeCreated)
1530             {
1531                 if (IsAdded())
1532                 {
1533                     RunIfNotReady();
1534                 }
1535             }
1536             return;
1537         }
1538     }
1539 
1540     /*
1541      * Process port activity
1542      */
1543     if (((iInterfaceState == EPVMFNodeInitialized) ||
1544             (iInterfaceState == EPVMFNodePrepared) ||
1545             (iInterfaceState == EPVMFNodeStarted)  ||
1546             (iInterfaceState == EPVMFNodePaused)) ||
1547             FlushPending())
1548     {
1549         uint32 i;
1550         for (i = 0; i < iPortVector.size(); i++)
1551         {
1552             PVMFJitterBufferPortParams* portContainerPtr =
1553                 iPortVector[i]->iPortParams;
1554 
1555             if (portContainerPtr == NULL)
1556             {
1557                 if (!getPortContainer(iPortVector[i], portContainerPtr))
1558                 {
1559                     PVMF_JBNODE_LOGERROR((0, "0x%x PVMFJitterBufferNode::Run: Error - getPortContainer failed", this));
1560                     return;
1561                 }
1562                 iPortVector[i]->iPortParams = portContainerPtr;
1563             }
1564 
1565             ProcessPortActivity(portContainerPtr);
1566         }
1567 
1568         if (CheckForPortRescheduling())
1569         {
1570             if (IsAdded())
1571             {
1572                 /*
1573                  * Re-schedule since there is atleast one port that needs processing
1574                  */
1575                 RunIfNotReady();
1576             }
1577             return;
1578         }
1579     }
1580 
1581     /*
1582      * If we get here we did not process any ports or commands.
1583      * Check for completion of a flush command...
1584      */
1585     if (FlushPending() && (!CheckForPortActivityQueues()))
1586     {
1587         uint32 i;
1588         /*
1589          * Debug check-- all the port queues should be empty at
1590          * this point.
1591          */
1592         for (i = 0; i < iPortVector.size(); i++)
1593         {
1594             if (iPortVector[i]->IncomingMsgQueueSize() > 0 ||
1595                     iPortVector[i]->OutgoingMsgQueueSize() > 0)
1596             {
1597                 OSCL_ASSERT(false);
1598             }
1599         }
1600         /*
1601          * Flush is complete.  Go to prepared state.
1602          */
1603         SetState(EPVMFNodePrepared);
1604         /*
1605          * resume port input so the ports can be re-started.
1606          */
1607         for (i = 0; i < iPortVector.size(); i++)
1608         {
1609             iPortVector[i]->ResumeInput();
1610         }
1611         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
1612         if (IsAdded())
1613         {
1614             RunIfNotReady();
1615         }
1616     }
1617     return;
1618 }
1619 
DoCancel()1620 void PVMFJitterBufferNode::DoCancel()
1621 {
1622     /*
1623      * the base class cancel operation is sufficient.
1624      */
1625     OsclActiveObject::DoCancel();
1626 }
1627 
ProcessPortActivity(PVMFJitterBufferPortParams * aPortParams)1628 bool PVMFJitterBufferNode::ProcessPortActivity(PVMFJitterBufferPortParams* aPortParams)
1629 {
1630     if (!aPortParams)
1631     {
1632         return false;
1633     }
1634 
1635     PVMFStatus status = PVMFSuccess;
1636     switch (aPortParams->iTag)
1637     {
1638         case PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT:
1639         {
1640             if ((aPortParams->iProcessOutgoingMessages) &&
1641                     (aPortParams->irPort.OutgoingMsgQueueSize() > 0))
1642             {
1643                 status = ProcessOutgoingMsg(aPortParams);
1644             }
1645             /*
1646              * Send data out of jitter buffer as long as there's:
1647              *  - more data to send
1648              *  - outgoing queue isn't in a Busy state.
1649              *  - ports are not paused
1650              */
1651             PVMFJitterBufferPort* outPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, &aPortParams->irPort);
1652             PVMFJitterBufferPortParams* inPortParamsPtr = outPort->iCounterpartPortParams;
1653             if (aPortParams->iProcessOutgoingMessages)
1654             {
1655                 if ((oStopOutputPorts == false) && (inPortParamsPtr->iCanReceivePktFromJB))
1656                 {
1657                     SendData(OSCL_STATIC_CAST(PVMFPortInterface*, &inPortParamsPtr->irPort));
1658                 }
1659             }
1660         }
1661         break;
1662 
1663         case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
1664         {
1665             PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ProcessPortActivity: input port- aPortParams->iProcessIncomingMessages %d aPortParams->iPort->IncomingMsgQueueSize()  %d" ,
1666                                  aPortParams->iProcessIncomingMessages, aPortParams->irPort.IncomingMsgQueueSize()));
1667             if ((aPortParams->iProcessIncomingMessages) &&
1668                     (aPortParams->irPort.IncomingMsgQueueSize() > 0))
1669             {
1670                 status = ProcessIncomingMsg(aPortParams);
1671             }
1672             if ((aPortParams->iProcessOutgoingMessages) &&
1673                     (aPortParams->irPort.OutgoingMsgQueueSize() > 0))
1674             {
1675                 status = ProcessOutgoingMsg(aPortParams);
1676             }
1677         }
1678         break;
1679 
1680         case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
1681         {
1682             PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ProcessPortActivity: - aPortParams->iProcessIncomingMessages %d aPortParams->iPort->IncomingMsgQueueSize()  %d" ,
1683                                  aPortParams->iProcessIncomingMessages, aPortParams->irPort.IncomingMsgQueueSize()));
1684 
1685             if ((aPortParams->iProcessIncomingMessages) &&
1686                     (aPortParams->irPort.IncomingMsgQueueSize() > 0))
1687             {
1688                 status = ProcessIncomingMsg(aPortParams);
1689             }
1690             if ((aPortParams->iProcessOutgoingMessages) &&
1691                     (aPortParams->irPort.OutgoingMsgQueueSize() > 0))
1692             {
1693                 status = ProcessOutgoingMsg(aPortParams);
1694             }
1695         }
1696         break;
1697 
1698         default:
1699             break;
1700     }
1701 
1702     /*
1703      * Report any unexpected failure in port processing...
1704      * (the InvalidState error happens when port input is suspended,
1705      * so don't report it.)
1706      */
1707     if (status != PVMFErrBusy
1708             && status != PVMFSuccess
1709             && status != PVMFErrInvalidState)
1710     {
1711         PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessPortActivity: Error - ProcessPortActivity failed. port=0x%x",
1712                               &aPortParams->irPort));
1713         ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(&aPortParams->irPort));
1714     }
1715 
1716     /*
1717      * return true if we processed an activity...
1718      */
1719     return (status != PVMFErrBusy);
1720 }
1721 
1722 ///////////////////////////////////////////////////////////////////////////////
1723 //Processing of incoming msg
1724 ///////////////////////////////////////////////////////////////////////////////
ProcessIncomingMsg(PVMFJitterBufferPortParams * aPortParams)1725 PVMFStatus PVMFJitterBufferNode::ProcessIncomingMsg(PVMFJitterBufferPortParams* aPortParams)
1726 {
1727     PVUuid eventuuid = PVMFJitterBufferNodeEventTypeUUID;
1728     PVMFPortInterface* aPort = &aPortParams->irPort;
1729 
1730     PVMF_JBNODE_LOGDATATRAFFIC_IN((0, "PVMFJitterBufferNode::ProcessIncomingMsg: %s Tag %d", aPortParams->iMimeType.get_cstr(), aPortParams->iTag));
1731 
1732     aPortParams->iNumMediaMsgsRecvd++;
1733 
1734     if (aPortParams->iMonitorForRemoteActivity == true)
1735     {
1736         CancelEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
1737         RequestEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
1738     }
1739 
1740     switch (aPortParams->iTag)
1741     {
1742         case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
1743         {
1744             /* Parse packet header - mainly to retrieve time stamp */
1745             PVMFJitterBuffer* jitterBuffer = aPortParams->ipJitterBuffer;
1746             if (jitterBuffer == NULL)
1747             {
1748                 PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessIncomingMsg: findJitterBuffer failed"));
1749                 int32 errcode = PVMFJitterBufferNodeUnableToRegisterIncomingPacket;
1750                 ReportErrorEvent(PVMFErrArgument, (OsclAny*)(aPort), &eventuuid, &errcode);
1751                 return PVMFErrArgument;
1752             }
1753 
1754             /*
1755              * Incoming message recvd on the input port.
1756              * Dequeue the message
1757              */
1758             PVMFSharedMediaMsgPtr msg;
1759             PVMFStatus status = aPort->DequeueIncomingMsg(msg);
1760             if (status != PVMFSuccess)
1761             {
1762                 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aPort));
1763                 PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Error - INPUT PORT - DequeueIncomingMsg failed"));
1764                 return status;
1765             }
1766 
1767             PVMFJitterBufferRegisterMediaMsgStatus regStatus = jitterBuffer->RegisterMediaMsg(msg);
1768             switch (regStatus)
1769             {
1770 
1771                 case PVMF_JB_REGISTER_MEDIA_MSG_SUCCESS:
1772                 {
1773                     PVMF_JBNODE_LOGDATATRAFFIC_IN((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Packet registered successfully Mime %s", aPortParams->iMimeType.get_cstr()));
1774                 }
1775                 break;
1776                 case PVMF_JB_REGISTER_MEDIA_MSG_FAILURE_JB_FULL:
1777                 {
1778                     aPortParams->iProcessIncomingMessages = false;
1779                     jitterBuffer->NotifyFreeSpaceAvailable();
1780                     int32 infocode = PVMFJitterBufferNodeJitterBufferFull;
1781                     ReportInfoEvent(PVMFInfoOverflow, (OsclAny*)(aPort), &eventuuid, &infocode);
1782                     PVMF_JBNODE_LOGDATATRAFFIC_IN((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Jitter Buffer full"));
1783                     PVMF_JBNODE_LOGDATATRAFFIC_FLOWCTRL_E((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Jitter Buffer full"));
1784                     return PVMFErrBusy;
1785                 }
1786                 break;
1787                 case PVMF_JB_REGISTER_MEDIA_MSG_FAILURE_INSUFFICIENT_MEMORY_FOR_PACKETIZATION:
1788                 {
1789                     aPortParams->iProcessIncomingMessages = false;
1790                     jitterBuffer->NotifyFreeSpaceAvailable();
1791                     return PVMFErrBusy;
1792                 }
1793                 break;
1794                 case PVMF_JB_REGISTER_MEDIA_MSG_ERR_CORRUPT_PACKET:
1795                 {
1796                     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessIncomingMsg: unable to register packet"));
1797                     int32 errcode = PVMFJitterBufferNodeUnableToRegisterIncomingPacket;
1798                     ReportErrorEvent(PVMFErrArgument, (OsclAny*)(aPort), &eventuuid, &errcode);
1799                     return PVMFErrArgument;
1800                 }
1801                 case PVMF_JB_REGISTER_MEDIA_MSG_ERR_EOS_SIGNALLED:
1802                 {
1803                     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessIncomingMsg: data received after signalling EOS"));
1804                 }
1805                 break;
1806                 default:
1807                 {
1808                     PVMF_JBNODE_LOGDATATRAFFIC_IN((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Packet could not be registered Register packet returned status %d", regStatus));
1809                     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Packet could not be registered Register packet returned status %d", regStatus));
1810                 }
1811             }
1812             SendData(aPort);
1813         }
1814         break;
1815 
1816         case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
1817         {
1818             /*
1819              * Incoming RTCP reports - recvd on the input port.
1820              * Dequeue the message - Need to fully implement
1821              * RTCP
1822              */
1823             PVMFSharedMediaMsgPtr msg;
1824             PVMFStatus status = aPort->DequeueIncomingMsg(msg);
1825             if (status != PVMFSuccess)
1826             {
1827                 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aPort));
1828                 PVMF_JBNODE_LOGERROR((0, "0x%x PVMFJitterBufferNode::ProcessIncomingMsg: Error - FB PORT - DequeueIncomingMsg failed", this));
1829                 return status;
1830             }
1831             status = ipJitterBufferMisc->ProcessFeedbackMessage(*aPortParams, msg);
1832             PVMF_JBNODE_LOGDATATRAFFIC_IN((0, "PVMFJitterBufferNode::ProcessIncomingMsg: Feedback Packet registered with status code status %d", status));
1833         }
1834         break;
1835 
1836         default:
1837         {
1838             ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aPort));
1839             PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ProcessIncomingMsg - Invalid Port Tag"));
1840             return PVMFFailure;
1841         }
1842     }
1843     return (PVMFSuccess);
1844 }
1845 
1846 ///////////////////////////////////////////////////////////////////////////////
1847 //Processing of outgoing msg
1848 ///////////////////////////////////////////////////////////////////////////////
ProcessOutgoingMsg(PVMFJitterBufferPortParams * aPortParams)1849 PVMFStatus PVMFJitterBufferNode::ProcessOutgoingMsg(PVMFJitterBufferPortParams* aPortParams)
1850 {
1851     PVMFPortInterface* aPort = &aPortParams->irPort;
1852     /*
1853      * Called by the AO to process one message off the outgoing
1854      * message queue for the given port.  This routine will
1855      * try to send the data to the connected port.
1856      */
1857     PVMF_JBNODE_LOGINFO((0, "0x%x PVMFJitterBufferNode::ProcessOutgoingMsg: aPort=0x%x", this, aPort));
1858 
1859     /*
1860      * If connected port is busy, the outgoing message cannot be process. It will be
1861      * queued to be processed again after receiving PORT_ACTIVITY_CONNECTED_PORT_READY
1862      * from this port.
1863      */
1864     if (aPort->IsConnectedPortBusy())
1865     {
1866         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "0x%x PVMFJitterBufferNode::ProcessOutgoingMsg: Connected port is busy", this));
1867         aPortParams->iProcessOutgoingMessages = false;
1868         return PVMFErrBusy;
1869     }
1870 
1871     PVMFStatus status = PVMFSuccess;
1872 
1873     status = aPort->Send();
1874     if (status == PVMFErrBusy)
1875     {
1876         PVMF_JBNODE_LOGDATATRAFFIC((0, "PVMFJitterBufferNode::ProcessOutgoingMsg: Connected port goes into busy state"));
1877         aPortParams->iProcessOutgoingMessages = false;
1878     }
1879     else
1880     {
1881         aPortParams->iNumMediaMsgsSent++;
1882     }
1883     return status;
1884 }
1885 
1886 PVMFStatus
SendData(PVMFPortInterface * aPort)1887 PVMFJitterBufferNode::SendData(PVMFPortInterface* aPort)
1888 {
1889     PVMFJitterBufferPort* jbPort =
1890         OSCL_STATIC_CAST(PVMFJitterBufferPort*, aPort);
1891 
1892     PVMFPortInterface* outputPort = jbPort->iPortCounterpart;
1893     PVMFJitterBufferPortParams* portParamsPtr = jbPort->iPortParams;
1894     PVMFJitterBufferPortParams* outPortParamsPtr = jbPort->iCounterpartPortParams;
1895     PVMFJitterBuffer* jitterBuffer = portParamsPtr->ipJitterBuffer;
1896 
1897     PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData In %s", outPortParamsPtr->iMimeType.get_cstr())) ;
1898 
1899     if (!(portParamsPtr->iCanReceivePktFromJB))
1900     {
1901         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData - Cant retrieve pkt from JB"));
1902         return PVMFFailure;
1903     }
1904 
1905     if (outPortParamsPtr->irPort.IsOutgoingQueueBusy())
1906     {
1907         outPortParamsPtr->iProcessOutgoingMessages = false;
1908         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData - Port found to be busy %s", outPortParamsPtr->iMimeType.get_cstr())) ;
1909         return PVMFErrBusy;
1910     }
1911 
1912     if (oStopOutputPorts)
1913     {
1914         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData from Mime[%s] Output ports Stopped--", jbPort->iPortParams->iMimeType.get_cstr()));
1915         return PVMFSuccess;
1916     }
1917 
1918     PVMFSharedMediaMsgPtr mediaOutMsg;
1919     bool cmdPacket = false;
1920     PVMFStatus status = jbPort->iPortParams->ipJitterBuffer->RetrievePacket(mediaOutMsg, cmdPacket);
1921     while (PVMFSuccess == status)
1922     {
1923         if (!cmdPacket)
1924         {
1925             //media msg
1926             outPortParamsPtr->iLastMsgTimeStamp = mediaOutMsg->getTimestamp();
1927         }
1928 
1929         status = outputPort->QueueOutgoingMsg(mediaOutMsg);
1930 
1931         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData from Mime[%s] MediaMsg SeqNum[%d], Ts[%d]", jbPort->iPortParams->iMimeType.get_cstr(), mediaOutMsg->getSeqNum(), mediaOutMsg->getTimestamp()));
1932 
1933         if (outPortParamsPtr->irPort.IsOutgoingQueueBusy())
1934         {
1935             outPortParamsPtr->iProcessOutgoingMessages = false;
1936             PVMFJitterBufferStats stats = jbPort->iPortParams->ipJitterBuffer->getJitterBufferStats();
1937             PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "Send Data Mime %s stats.currentOccupancy[%d], stats.maxSeqNumRegistered[%d], stats.lastRetrievedSeqNum[%d] stats.maxTimeStampRetrievedWithoutRTPOffset[%d] SendOut Pkt[%d]", jbPort->iPortParams->iMimeType.get_cstr(), stats.currentOccupancy, stats.maxSeqNumRegistered, stats.lastRetrievedSeqNum, stats.maxTimeStampRetrievedWithoutRTPOffset, outPortParamsPtr->iNumMediaMsgsSent));
1938             return PVMFErrBusy;
1939         }
1940         status = jbPort->iPortParams->ipJitterBuffer->RetrievePacket(mediaOutMsg, cmdPacket);
1941     }
1942 
1943     if (PVMFErrNotReady == status)
1944     {
1945         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData from Mime[%s] JB not ready", jbPort->iPortParams->iMimeType.get_cstr()));
1946 
1947 
1948         uint32 currentTime32 = 0;
1949         uint32 currentTimeBase32 = 0;
1950         bool overflowFlag = false;
1951         ipJitterBufferMisc->GetEstimatedServerClock().GetCurrentTime32(currentTime32,
1952                 overflowFlag,
1953                 PVMF_MEDIA_CLOCK_MSEC,
1954                 currentTimeBase32);
1955 
1956 
1957         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData - Estimated serv clock %d", currentTime32));
1958         currentTime32 = 0;
1959         currentTimeBase32 = 0;
1960         ipClientPlayBackClock->GetCurrentTime32(currentTime32,
1961                                                 overflowFlag,
1962                                                 PVMF_MEDIA_CLOCK_MSEC,
1963                                                 currentTimeBase32);
1964         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData - Client serv clock %d", currentTime32));
1965 
1966 
1967         PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::SendData - Occupancy is %d delayestablish %d", jbPort->iPortParams->ipJitterBuffer->getJitterBufferStats().currentOccupancy, iDelayEstablished));
1968 
1969         portParamsPtr->iCanReceivePktFromJB = false;
1970         jitterBuffer->NotifyCanRetrievePacket();
1971         return PVMFErrNotReady;
1972     }
1973 
1974     return status;
1975 }
1976 
CheckForPortRescheduling()1977 bool PVMFJitterBufferNode::CheckForPortRescheduling()
1978 {
1979     //This method is only called from JB Node AO's Run.
1980     //Purpose of this method is to determine whether the node
1981     //needs scheduling based on any outstanding port activities
1982     //Here is the scheduling criteria for different port types:
1983     //a) PVMF_JITTER_BUFFER_PORT_TYPE_INPUT - If there are incoming
1984     //msgs waiting in incoming msg queue then node needs scheduling,
1985     //as long oProcessIncomingMessages is true. This boolean stays true
1986     //as long we can register packets in JB. If JB is full this boolean
1987     //is made false (when CheckForSpaceInJitterBuffer() returns false)
1988     //and is once again made true in JitterBufferFreeSpaceAvailable() callback.
1989     //We also use the input port briefly as a bidirectional port in case of
1990     //RTSP streaming to do firewall packet exchange. So if there are outgoing
1991     //msgs and oProcessOutgoingMessages is true then node needs scheduling.
1992     //b) PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT - As long as:
1993     //  - there are msgs in outgoing queue
1994     //  - oProcessOutgoingMessages is true
1995     //  - and as long as there is data in JB and we are not in buffering
1996     //then node needs scheduling.
1997     //c) PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK - As long as:
1998     //  - there are msgs in incoming queue and oProcessIncomingMessages is true
1999     //  - there are msgs in outgoing queue and oProcessOutgoingMessages is true
2000     uint32 i;
2001     for (i = 0; i < iPortVector.size(); i++)
2002     {
2003         PVMFJitterBufferPortParams* portContainerPtr = iPortVector[i]->iPortParams;
2004         if (portContainerPtr == NULL)
2005         {
2006             PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::CheckForPortRescheduling: Error - GetPortContainer failed"));
2007             return false;
2008         }
2009         if (portContainerPtr->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
2010         {
2011             if (portContainerPtr->irPort.IncomingMsgQueueSize() > 0)
2012             {
2013                 if (portContainerPtr->iProcessIncomingMessages)
2014                 {
2015                     /*
2016                      * Found a port that has outstanding activity and
2017                      * is not busy.
2018                      */
2019                     return true;
2020                 }
2021             }
2022             if (portContainerPtr->irPort.OutgoingMsgQueueSize() > 0)
2023             {
2024                 if (portContainerPtr->iProcessOutgoingMessages)
2025                 {
2026                     /*
2027                      * Found a port that has outstanding activity and
2028                      * is not busy.
2029                      */
2030                     return true;
2031                 }
2032             }
2033         }
2034         else if (portContainerPtr->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT)
2035         {
2036             PVMFJitterBufferPort* jbPort =
2037                 OSCL_STATIC_CAST(PVMFJitterBufferPort*, &portContainerPtr->irPort);
2038             PVMFJitterBufferPortParams* inPortParamsPtr = jbPort->iCounterpartPortParams;
2039             if ((portContainerPtr->irPort.OutgoingMsgQueueSize() > 0) ||
2040                     (inPortParamsPtr->iCanReceivePktFromJB))
2041             {
2042                 if ((portContainerPtr->iProcessOutgoingMessages) && (oStopOutputPorts == false))
2043                 {
2044                     /*
2045                      * Found a port that has outstanding activity and
2046                      * is not busy.
2047                      */
2048                     return true;
2049                 }
2050             }
2051         }
2052         else if (portContainerPtr->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK)
2053         {
2054             if (portContainerPtr->irPort.IncomingMsgQueueSize() > 0)
2055             {
2056                 if (portContainerPtr->iProcessIncomingMessages)
2057                 {
2058                     /*
2059                      * Found a port that has outstanding activity and
2060                      * is not busy.
2061                      */
2062                     return true;
2063                 }
2064             }
2065             if (portContainerPtr->irPort.OutgoingMsgQueueSize() > 0)
2066             {
2067                 if (portContainerPtr->iProcessOutgoingMessages)
2068                 {
2069                     /*
2070                      * Found a port that has outstanding activity and
2071                      * is not busy.
2072                      */
2073                     return true;
2074                 }
2075             }
2076         }
2077     }
2078     /*
2079      * No port processing needed - either all port activity queues are empty
2080      * or the ports are backed up due to flow control.
2081      */
2082     return false;
2083 }
2084 
CheckForPortActivityQueues()2085 bool PVMFJitterBufferNode::CheckForPortActivityQueues()
2086 {
2087     uint32 i;
2088     for (i = 0; i < iPortVector.size(); i++)
2089     {
2090         PVMFJitterBufferPortParams* portContainerPtr = NULL;
2091 
2092         if (!getPortContainer(iPortVector[i], portContainerPtr))
2093         {
2094             PVMF_JBNODE_LOGERROR((0, "0x%x PVMFJitterBufferNode::CheckForPortActivityQueues: Error - GetPortContainer failed", this));
2095             return false;
2096         }
2097 
2098         if ((portContainerPtr->irPort.IncomingMsgQueueSize() > 0) ||
2099                 (portContainerPtr->irPort.OutgoingMsgQueueSize() > 0))
2100         {
2101             /*
2102              * Found a port that still has an outstanding activity.
2103              */
2104             return true;
2105         }
2106     }
2107 
2108     return false;
2109 }
2110 
2111 /**
2112  * A routine to tell if a flush operation is in progress.
2113  */
FlushPending()2114 bool PVMFJitterBufferNode::FlushPending()
2115 {
2116     return (iCurrentCommand.size() > 0
2117             && iCurrentCommand.front().iCmd == PVMF_JITTER_BUFFER_NODE_FLUSH);
2118 }
2119 
2120 // Called by the command handler AO to process a command from
2121 // the input queue.
2122 // Return true if a command was processed, false if the command
2123 // processor is busy and can't process another command now.
2124 
ProcessCommand(PVMFJitterBufferNodeCommand & aCmd)2125 bool PVMFJitterBufferNode::ProcessCommand(PVMFJitterBufferNodeCommand& aCmd)
2126 {
2127     /*
2128      * normally this node will not start processing one command
2129      * until the prior one is finished.  However, a hi priority
2130      * command such as Cancel must be able to interrupt a command
2131      * in progress.
2132      */
2133     if (!iCurrentCommand.empty() && !aCmd.hipri())
2134         return false;
2135 
2136     switch (aCmd.iCmd)
2137     {
2138         case PVMF_JITTER_BUFFER_NODE_QUERYUUID:
2139             DoQueryUuid(aCmd);
2140             break;
2141 
2142         case PVMF_JITTER_BUFFER_NODE_QUERYINTERFACE:
2143             DoQueryInterface(aCmd);
2144             break;
2145 
2146         case PVMF_JITTER_BUFFER_NODE_REQUESTPORT:
2147             DoRequestPort(aCmd);
2148             break;
2149 
2150         case PVMF_JITTER_BUFFER_NODE_RELEASEPORT:
2151             DoReleasePort(aCmd);
2152             break;
2153 
2154         case PVMF_JITTER_BUFFER_NODE_INIT:
2155             DoInit(aCmd);
2156             break;
2157 
2158         case PVMF_JITTER_BUFFER_NODE_PREPARE:
2159             DoPrepare(aCmd);
2160             break;
2161 
2162         case PVMF_JITTER_BUFFER_NODE_START:
2163             DoStart(aCmd);
2164             break;
2165 
2166         case PVMF_JITTER_BUFFER_NODE_STOP:
2167             DoStop(aCmd);
2168             break;
2169 
2170         case PVMF_JITTER_BUFFER_NODE_FLUSH:
2171             DoFlush(aCmd);
2172             break;
2173 
2174         case PVMF_JITTER_BUFFER_NODE_PAUSE:
2175             DoPause(aCmd);
2176             break;
2177 
2178         case PVMF_JITTER_BUFFER_NODE_RESET:
2179             DoReset(aCmd);
2180             break;
2181 
2182         case PVMF_JITTER_BUFFER_NODE_CANCELALLCOMMANDS:
2183             DoCancelAllCommands(aCmd);
2184             break;
2185 
2186         case PVMF_JITTER_BUFFER_NODE_CANCELCOMMAND:
2187             DoCancelCommand(aCmd);
2188             break;
2189 
2190         default:
2191         {
2192             /* unknown command type */
2193             CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
2194         }
2195         break;
2196     }
2197 
2198     return true;
2199 }
2200 
2201 void
MoveCmdToCurrentQueue(PVMFJitterBufferNodeCommand & aCmd)2202 PVMFJitterBufferNode::MoveCmdToCurrentQueue(PVMFJitterBufferNodeCommand& aCmd)
2203 {
2204     int32 err;
2205     OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
2206     if (err != OsclErrNone)
2207     {
2208         CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
2209         return;
2210     }
2211     iInputCommands.Erase(&aCmd);
2212     return;
2213 }
2214 
CommandComplete(PVMFJitterBufferNodeCmdQ & aCmdQ,PVMFJitterBufferNodeCommand & aCmd,PVMFStatus aStatus,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)2215 void PVMFJitterBufferNode::CommandComplete(PVMFJitterBufferNodeCmdQ& aCmdQ,
2216         PVMFJitterBufferNodeCommand& aCmd,
2217         PVMFStatus aStatus,
2218         OsclAny* aEventData,
2219         PVUuid* aEventUUID,
2220         int32* aEventCode)
2221 {
2222     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
2223                          , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
2224 
2225     PVInterface* extif = NULL;
2226     PVMFBasicErrorInfoMessage* errormsg = NULL;
2227     if (aEventUUID && aEventCode)
2228     {
2229         PVMF_JITTER_BUFFER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), errormsg);
2230         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
2231     }
2232 
2233     /* create response */
2234     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
2235     PVMFSessionId session = aCmd.iSession;
2236 
2237     /* Erase the command from the queue */
2238     aCmdQ.Erase(&aCmd);
2239 
2240     /* Report completion to the session observer */
2241     ReportCmdCompleteEvent(session, resp);
2242 
2243     if (errormsg)
2244     {
2245         errormsg->removeRef();
2246     }
2247 
2248     /*
2249      * Transition to error state in case of select errors only, viz.
2250      * PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
2251      * Any other status implies that the node is probably in a recoverable
2252      * state
2253      */
2254     if ((aStatus == PVMFFailure) ||
2255             (aStatus == PVMFErrNoMemory) ||
2256             (aStatus == PVMFErrNoResources))
2257     {
2258         SetState(EPVMFNodeError);
2259     }
2260 }
2261 
CommandComplete(PVMFJitterBufferNodeCommand & aCmd,PVMFStatus aStatus,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)2262 void PVMFJitterBufferNode::CommandComplete(PVMFJitterBufferNodeCommand& aCmd,
2263         PVMFStatus aStatus,
2264         OsclAny* aEventData,
2265         PVUuid* aEventUUID,
2266         int32* aEventCode)
2267 {
2268     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
2269                          , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
2270 
2271     PVInterface* extif = NULL;
2272     PVMFBasicErrorInfoMessage* errormsg = NULL;
2273     if (aEventUUID && aEventCode)
2274     {
2275         PVMF_JITTER_BUFFER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), errormsg);
2276         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
2277     }
2278 
2279     /* create response */
2280     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
2281     PVMFSessionId session = aCmd.iSession;
2282 
2283     /* Report completion to the session observer */
2284     ReportCmdCompleteEvent(session, resp);
2285 
2286     if (errormsg)
2287     {
2288         errormsg->removeRef();
2289     }
2290     /*
2291      * Transition to error state in case of select errors only, viz.
2292      * PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
2293      * Any other status implies that the node is probably in a recoverable
2294      * state
2295      */
2296     if ((aStatus == PVMFFailure) ||
2297             (aStatus == PVMFErrNoMemory) ||
2298             (aStatus == PVMFErrNoResources))
2299     {
2300         SetState(EPVMFNodeError);
2301     }
2302 }
2303 
2304 /**
2305  * The various command handlers call this when a INTERNAL command is complete.
2306  * Does not report completion as it is an internal command
2307  */
InternalCommandComplete(PVMFJitterBufferNodeCmdQ & aCmdQ,PVMFJitterBufferNodeCommand & aCmd,PVMFStatus aStatus,OsclAny * aEventData)2308 void PVMFJitterBufferNode::InternalCommandComplete(PVMFJitterBufferNodeCmdQ& aCmdQ,
2309         PVMFJitterBufferNodeCommand& aCmd,
2310         PVMFStatus aStatus,
2311         OsclAny* aEventData)
2312 {
2313     OSCL_UNUSED_ARG(aEventData);
2314 
2315     PVMF_JBNODE_LOGINFO((0, "JitterBufferNode:InternalCommandComplete Id %d Cmd %d Status %d Context %d Data %d"
2316                          , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
2317 
2318     /* Erase the command from the queue */
2319     aCmdQ.Erase(&aCmd);
2320 
2321     /*
2322      * Transition to error state in case of select errors only, viz.
2323      * PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
2324      * Any other status implies that the node is probably in a recoverable
2325      * state
2326      */
2327     if ((aStatus == PVMFFailure) ||
2328             (aStatus == PVMFErrNoMemory) ||
2329             (aStatus == PVMFErrNoResources))
2330     {
2331         SetState(EPVMFNodeError);
2332     }
2333 }
2334 
2335 ///////////////////////////////////////////////////////////////////////////////
2336 //Called by the command handler AO to do the Query UUID
2337 ///////////////////////////////////////////////////////////////////////////////
DoQueryUuid(PVMFJitterBufferNodeCommand & aCmd)2338 void PVMFJitterBufferNode::DoQueryUuid(PVMFJitterBufferNodeCommand& aCmd)
2339 {
2340     // This node supports Query UUID from any state
2341     OSCL_String* mimetype;
2342     Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
2343     bool exactmatch;
2344     aCmd.PVMFJitterBufferNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
2345 
2346     // Try to match the input mimetype against any of
2347     // the custom interfaces for this node
2348 
2349     // Match against custom interface1...
2350     // also match against base mimetypes for custom interface1,
2351     // unless exactmatch is set.
2352 
2353     if (*mimetype == PVMF_JITTERBUFFER_CUSTOMINTERFACE_MIMETYPE
2354             || (!exactmatch && *mimetype == PVMF_JITTERBUFFER_MIMETYPE)
2355             || (!exactmatch && *mimetype == PVMF_JITTERBUFFER_BASEMIMETYPE))
2356     {
2357         PVUuid uuid(PVMF_JITTERBUFFERNODE_EXTENSIONINTERFACE_UUID);
2358         uuidvec->push_back(uuid);
2359     }
2360     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2361 }
2362 
2363 ///////////////////////////////////////////////////////////////////////////////
2364 //Called by the command handler AO to do the Query Interface.
2365 ///////////////////////////////////////////////////////////////////////////////
DoQueryInterface(PVMFJitterBufferNodeCommand & aCmd)2366 void PVMFJitterBufferNode::DoQueryInterface(PVMFJitterBufferNodeCommand& aCmd)
2367 {
2368     //This node supports Query Interface from any state
2369     PVUuid* uuid;
2370     PVInterface** ptr;
2371     aCmd.PVMFJitterBufferNodeCommandBase::Parse(uuid, ptr);
2372 
2373     if (*uuid == PVUuid(PVMF_JITTERBUFFERNODE_EXTENSIONINTERFACE_UUID))
2374     {
2375         if (!ipExtensionInterface)
2376         {
2377             OsclMemAllocator alloc;
2378             int32 err;
2379             OsclAny*ptr = NULL;
2380             OSCL_TRY(err,
2381                      ptr = alloc.ALLOCATE(sizeof(PVMFJitterBufferExtensionInterfaceImpl));
2382                     );
2383             if (err != OsclErrNone || !ptr)
2384             {
2385                 PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoQueryInterface: Error - Out of memory"));
2386                 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
2387                 return;
2388             }
2389             ipExtensionInterface =
2390                 OSCL_PLACEMENT_NEW(ptr, PVMFJitterBufferExtensionInterfaceImpl(this));
2391         }
2392         if (ipExtensionInterface->queryInterface(*uuid, *ptr))
2393         {
2394             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2395         }
2396         else
2397         {
2398             CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
2399         }
2400     }
2401     else
2402     {
2403         // not supported
2404         *ptr = NULL;
2405         CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
2406     }
2407 }
2408 
2409 ///////////////////////////////////////////////////////////////////////////////
2410 // Called by the command handler AO to do the port request
2411 // Decides the type of requested port
2412 // Reserve space in port vector for the new port
2413 // Instantiate the port and push it in the port vector
2414 // Populate portparms for tag (port type), jitterbuffer, port, iId,
2415 //
2416 ///////////////////////////////////////////////////////////////////////////////
DoRequestPort(PVMFJitterBufferNodeCommand & aCmd)2417 void PVMFJitterBufferNode::DoRequestPort(PVMFJitterBufferNodeCommand& aCmd)
2418 {
2419     // This node supports port request from any state
2420     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DoRequestPort"));
2421 
2422     // retrieve port tag
2423     int32 tag;
2424     OSCL_String* mimetype;
2425     aCmd.PVMFJitterBufferNodeCommandBase::Parse(tag, mimetype);
2426 
2427     PVMFJitterBufferNodePortTag jitterbufferPortTag = PVMF_JITTER_BUFFER_PORT_TYPE_INPUT;
2428 
2429     if (tag % 3)
2430     {
2431         if (tag % 3 == 1)
2432         {
2433             jitterbufferPortTag = PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT;
2434         }
2435         else if (tag % 3 == 2)
2436         {
2437             jitterbufferPortTag = PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK;
2438         }
2439     }
2440     else
2441     {
2442         jitterbufferPortTag = PVMF_JITTER_BUFFER_PORT_TYPE_INPUT;
2443     }
2444 
2445     // Input ports have tags: 0, 3, 6, ...
2446     // Output ports have tags: 1, 4, 7, ...
2447     // Feedback ports have tags: 2, 5, 8, ...
2448 
2449     //set port name for datapath logging.
2450     OSCL_StackString<20> portname;
2451     switch (jitterbufferPortTag)
2452     {
2453         case PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT:
2454             portname = "JitterBufOut";
2455             break;
2456         case PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK:
2457             //don't log this port for now...
2458             //portname="JitterBufFeedback";
2459             break;
2460         case PVMF_JITTER_BUFFER_PORT_TYPE_INPUT:
2461             //don't log this port for now...
2462             //portname="JitterBufIn";
2463             break;
2464         default:
2465             // avoid compiler warning
2466             break;
2467     }
2468 
2469     // Allocate a new port
2470     OsclAny *ptr = AllocatePort();
2471     if (!ptr)
2472     {
2473         PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoRequestPort: Error - iPortVector Out of memory"));
2474         CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
2475         return;
2476     }
2477 
2478     OsclExclusivePtr<PVMFJitterBufferPort> portAutoPtr;
2479     PVMFJitterBufferPort* port = NULL;
2480 
2481     OsclExclusivePtr<PVMFJitterBuffer> jitterBufferAutoPtr;
2482 
2483     // create base port with default settings
2484     port = OSCL_PLACEMENT_NEW(ptr, PVMFJitterBufferPort(tag, *this, portname.get_str()));
2485     portAutoPtr.set(port);
2486 
2487     /* Add the port to the port vector. */
2488     if (!PushPortToVect(port))
2489     {
2490         CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
2491         return;
2492     }
2493 
2494     PVMFJitterBufferPortParams* pPortParams = OSCL_NEW(PVMFJitterBufferPortParams, (*port));
2495     pPortParams->iTag = jitterbufferPortTag;
2496     PVMFJitterBuffer* jbPtr = NULL;
2497     pPortParams->ipJitterBuffer = NULL;
2498     pPortParams->iId = tag;
2499     if (mimetype != NULL)
2500     {
2501         pPortParams->iMimeType = mimetype->get_str();
2502     }
2503 
2504     // create jitter buffer if input port
2505     if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
2506     {
2507         PVMFJitterBufferConstructParams jbConstructParams(ipJitterBufferMisc->GetEstimatedServerClock(), *ipClientPlayBackClock, pPortParams->iMimeType, *ipJitterBufferMisc->GetEventNotifier(), iDelayEstablished, iJitterDelayPercent, iJitterBufferState, this, port);
2508         jbPtr = ipJitterBufferFactory->Create(jbConstructParams);
2509         if (jbPtr)
2510             jbPtr->SetDurationInMilliSeconds(iJitterBufferDurationInMilliSeconds);
2511         jitterBufferAutoPtr.set(jbPtr);
2512         pPortParams->ipJitterBuffer = jbPtr;
2513         if (iBroadCastSession == true)
2514         {
2515             jbPtr->SetBroadCastSession();
2516         }
2517     }
2518 
2519     if (!PushPortParamsToQ(pPortParams))
2520     {
2521         PVMF_JBNODE_LOGERROR((0, "0x%x PVMFJitterBufferNode::DoRequestPort: Error - iPortParamsQueue.push_back() failed", this));
2522         CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
2523         return;
2524     }
2525 
2526 
2527     // Update the iPortParams for all existing ports since adding a new Port Parameters element might
2528     // have caused reallocation of the vector elements.
2529     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
2530     for (it = iPortParamsQueue.begin();
2531             it != iPortParamsQueue.end();
2532             it++)
2533     {
2534         PVMFJitterBufferPortParams* portParametersPtr = *it;
2535         PVMFJitterBufferPort* portPtr = OSCL_REINTERPRET_CAST(PVMFJitterBufferPort*, &portParametersPtr->irPort);
2536         portPtr->iPortParams = portParametersPtr;
2537 
2538         // Update also the port counterpart and port counterpart parameters
2539         PVMFPortInterface* cpPort = getPortCounterpart(portPtr);
2540         if (cpPort != NULL)
2541         {
2542             portPtr->iPortCounterpart = (PVMFJitterBufferPort*)cpPort;
2543             PVMFJitterBufferPortParams* cpPortContainerPtr = NULL;
2544             if (getPortContainer(portPtr->iPortCounterpart, cpPortContainerPtr))
2545             {
2546                 portPtr->iCounterpartPortParams = cpPortContainerPtr;
2547             }
2548             else
2549             {
2550                 PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoRequestPort: getPortContainer for port counterpart failed"));
2551                 CommandComplete(iInputCommands, aCmd, PVMFFailure);
2552                 return;
2553             }
2554         }
2555 
2556     }
2557 
2558     portAutoPtr.release();
2559     jitterBufferAutoPtr.release();
2560 
2561 
2562     /* Return the port pointer to the caller. */
2563     CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port);
2564 }
2565 
AllocatePort()2566 OsclAny* PVMFJitterBufferNode::AllocatePort()
2567 {
2568     OsclAny *ptr = NULL;
2569     int32 err;
2570     OSCL_TRY(err, ptr = iPortVector.Allocate(););
2571     if (err != OsclErrNone)
2572     {
2573         ptr = NULL;
2574     }
2575     return ptr;
2576 }
2577 
PushPortToVect(PVMFJitterBufferPort * & aPort)2578 bool PVMFJitterBufferNode::PushPortToVect(PVMFJitterBufferPort*& aPort)
2579 {
2580     int32 err;
2581     OSCL_TRY(err, iPortVector.AddL(aPort););
2582     if (err != OsclErrNone)
2583     {
2584         return false;
2585     }
2586     return true;
2587 }
2588 
PushPortParamsToQ(PVMFJitterBufferPortParams * & aPortParams)2589 bool PVMFJitterBufferNode::PushPortParamsToQ(PVMFJitterBufferPortParams*& aPortParams)
2590 {
2591     int32 err;
2592     OSCL_TRY(err, iPortParamsQueue.push_back(aPortParams););
2593     if (err != OsclErrNone)
2594     {
2595         return false;
2596     }
2597     return true;
2598 }
2599 
2600 /**
2601  * Called by the command handler AO to do the port release
2602  */
DoReleasePort(PVMFJitterBufferNodeCommand & aCmd)2603 void PVMFJitterBufferNode::DoReleasePort(PVMFJitterBufferNodeCommand& aCmd)
2604 {
2605     /*This node supports release port from any state*/
2606 
2607     /* Find the port in the port vector */
2608     ResetNodeParams();
2609 
2610     PVMFPortInterface* p = NULL;
2611     aCmd.PVMFJitterBufferNodeCommandBase::Parse(p);
2612 
2613     PVMFJitterBufferPort* port = (PVMFJitterBufferPort*)p;
2614 
2615     PVMFJitterBufferPort** portPtr = iPortVector.FindByValue(port);
2616     if (portPtr)
2617     {
2618         /* delete corresponding port params */
2619         Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
2620 
2621         for (it = iPortParamsQueue.begin();
2622                 it != iPortParamsQueue.end();
2623                 it++)
2624         {
2625             PVMFJitterBufferPortParams* pPortParams = *it;
2626             if (&pPortParams->irPort == iPortVector.front())
2627             {
2628                 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
2629                 {
2630                     ipJitterBufferFactory->Destroy(pPortParams->ipJitterBuffer);
2631                 }
2632                 iPortParamsQueue.erase(it);
2633                 break;
2634             }
2635         }
2636         /* delete the port */
2637         iPortVector.Erase(portPtr);
2638 
2639         CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2640     }
2641     else
2642     {
2643         /* port not found */
2644         CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
2645     }
2646 }
2647 
2648 ///////////////////////////////////////////////////////////////////////////////
2649 // Called by the command handler AO to initialize the node
2650 // Decides the type of requested port
2651 // Reserve space in port vector for the new port
2652 // Instantiate the port and push it in the port vector
2653 // Populate portparms for tag (port type), jitterbuffer, port, iId,
2654 //
2655 ///////////////////////////////////////////////////////////////////////////////
DoInit(PVMFJitterBufferNodeCommand & aCmd)2656 void PVMFJitterBufferNode::DoInit(PVMFJitterBufferNodeCommand& aCmd)
2657 {
2658     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DoInit"));
2659     switch (iInterfaceState)
2660     {
2661         case EPVMFNodeIdle:
2662             if (ipJitterBufferMisc)
2663             {
2664                 ipJitterBufferMisc->Reset();
2665                 OSCL_DELETE(ipJitterBufferMisc);
2666                 ipJitterBufferMisc = NULL;
2667             }
2668             ipJitterBufferMisc = PVMFJitterBufferMisc::New(this, *ipClientPlayBackClock, iPortParamsQueue);
2669             if (ipJitterBufferMisc)
2670             {
2671                 ipEventNotifier = ipJitterBufferMisc->GetEventNotifier();
2672                 if (iBroadCastSession == true)
2673                     ipJitterBufferMisc->SetBroadcastSession();
2674             }
2675 
2676             SetState(EPVMFNodeInitialized);
2677             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2678             break;
2679 
2680         default:
2681             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
2682             break;
2683     }
2684 }
2685 
2686 /**
2687  * Called by the command handler AO to do the node Prepare
2688  */
DoPrepare(PVMFJitterBufferNodeCommand & aCmd)2689 void PVMFJitterBufferNode::DoPrepare(PVMFJitterBufferNodeCommand& aCmd)
2690 {
2691     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DoPrepare"));
2692     switch (iInterfaceState)
2693     {
2694         case EPVMFNodeInitialized:
2695         {
2696             uint32 i;
2697             for (i = 0; i < iPortVector.size(); i++)
2698             {
2699                 PVMFJitterBufferPortParams* portContainerPtr1 = NULL;
2700                 if (getPortContainer(iPortVector[i], portContainerPtr1))
2701                 {
2702                     iPortVector[i]->iPortParams = portContainerPtr1;
2703                 }
2704                 else
2705                 {
2706                     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoPrepare: getPortContainer - Self"));
2707                     CommandComplete(iInputCommands, aCmd, PVMFFailure);
2708                     break;
2709                 }
2710                 PVMFPortInterface* cpPort = getPortCounterpart(iPortVector[i]);
2711                 if (cpPort != NULL)
2712                 {
2713                     iPortVector[i]->iPortCounterpart = (PVMFJitterBufferPort*)cpPort;
2714                     PVMFJitterBufferPortParams* portContainerPtr2 = NULL;
2715                     if (getPortContainer(iPortVector[i]->iPortCounterpart, portContainerPtr2))
2716                     {
2717                         iPortVector[i]->iCounterpartPortParams = portContainerPtr2;
2718                     }
2719                     else
2720                     {
2721                         PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoPrepare: getPortContainer - Counterpart"));
2722                         CommandComplete(iInputCommands, aCmd, PVMFFailure);
2723                         break;
2724                     }
2725                 }
2726             }
2727 
2728             ipJitterBufferMisc->Prepare();
2729             PVMFStatus status = ipJitterBufferMisc->PrepareMediaReceivingChannel();
2730             if (PVMFPending == status)
2731             {
2732                 MoveCmdToCurrentQueue(aCmd);
2733             }
2734             else
2735             {
2736                 if (PVMFSuccess == status)
2737                 {
2738                     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DoPrepare: FW Pkts Disabled"));
2739                     /* Complete prepare */
2740                     SetState(EPVMFNodePrepared);
2741                     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2742                 }
2743                 else
2744                 {
2745                     CommandComplete(iInputCommands, aCmd, status);
2746                 }
2747             }
2748         }
2749         break;
2750 
2751         default:
2752             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
2753             break;
2754     }
2755 }
2756 
CompletePrepare()2757 void PVMFJitterBufferNode::CompletePrepare()
2758 {
2759     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::CompletePrepare"));
2760     SetState(EPVMFNodePrepared);
2761     PVMFJitterBufferNodeCommand cmd = iCurrentCommand.front();
2762     CommandComplete(cmd, PVMFSuccess);
2763     iCurrentCommand.Erase(&iCurrentCommand.front());
2764     return;
2765 }
2766 
CancelPrepare()2767 void PVMFJitterBufferNode::CancelPrepare()
2768 {
2769     ipJitterBufferMisc->CancelMediaReceivingChannelPreparation();
2770     PVMFJitterBufferNodeCommand cmd = iCurrentCommand.front();
2771     CommandComplete(cmd, PVMFErrCancelled);
2772     iCurrentCommand.Erase(&iCurrentCommand.front());
2773     return;
2774 }
2775 
2776 /**
2777  * Called by the command handler AO to do the node Start
2778  */
DoStart(PVMFJitterBufferNodeCommand & aCmd)2779 void PVMFJitterBufferNode::DoStart(PVMFJitterBufferNodeCommand& aCmd)
2780 {
2781     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DoStart"));
2782     PVMFStatus status = PVMFSuccess;
2783     switch (iInterfaceState)
2784     {
2785         case EPVMFNodePrepared:
2786         case EPVMFNodePaused:
2787         {
2788             ipJitterBufferMisc->StreamingSessionStarted();
2789             /* Diagnostic logging */
2790             iDiagnosticsLogged = false;
2791             iMediaReceiveingChannelPrepared = true;
2792 
2793             if (iInterfaceState == EPVMFNodePaused)
2794             {
2795                 uint32 currticks = OsclTickCount::TickCount();
2796                 uint32 startTime = OsclTickCount::TicksToMsec(currticks);
2797                 uint32 diff = (startTime - iPauseTime);
2798                 if (diff > PVMF_JITTER_BUFFER_NODE_FIREWALL_PKT_DEFAULT_PAUSE_DURATION_IN_MS)
2799                 {
2800                     if (PVMFPending == ipJitterBufferMisc->PrepareMediaReceivingChannel())
2801                     {
2802                         iMediaReceiveingChannelPrepared = false;
2803                     }
2804                 }
2805             }
2806 
2807             if (!ipJitterBufferMisc->IsSessionExpired())
2808                 RequestEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
2809 
2810             /* If auto paused, implies jitter buffer is not empty */
2811             if ((iDelayEstablished == false) ||
2812                     (iJitterBufferState == PVMF_JITTER_BUFFER_IN_TRANSITION))
2813             {
2814 
2815                 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
2816                 for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end(); iter++)
2817                 {
2818                     PVMFJitterBufferPortParams* pPortParams = *iter;
2819                     if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
2820                     {
2821                         pPortParams->ipJitterBuffer->NotifyCanRetrievePacket();
2822                     }
2823                 }
2824                 /*
2825                  * Move start to current msg queue where it would stay
2826                  * jitter buffer is full.
2827                  */
2828                 oStartPending = true;
2829                 MoveCmdToCurrentQueue(aCmd);
2830                 ReportInfoEvent(PVMFInfoBufferingStart);
2831                 RequestEventCallBack(JB_NOTIFY_REPORT_BUFFERING_STATUS);
2832             }
2833             else
2834             {
2835                 if (false == iMediaReceiveingChannelPrepared)
2836                 {
2837                     oStartPending = true;
2838                     MoveCmdToCurrentQueue(aCmd);
2839                 }
2840                 else
2841                 {
2842                     /* Just resuming from a paused state with enough data in jitter buffer */
2843                     oStartPending = false;
2844                     SetState(EPVMFNodeStarted);
2845                     /* Enable Output Ports */
2846                     StartOutputPorts();
2847                     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2848                 }
2849             }
2850         }
2851         break;
2852 
2853         default:
2854             status = PVMFErrInvalidState;
2855             CommandComplete(iInputCommands, aCmd, status);
2856             break;
2857     }
2858     return;
2859 }
2860 
CompleteStart()2861 void PVMFJitterBufferNode::CompleteStart()
2862 {
2863     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::CompleteStart"));
2864     PVMF_JBNODE_LOGDATATRAFFIC((0, "PVMFJitterBufferNode::CompleteStart"));
2865 
2866     if (!iMediaReceiveingChannelPrepared)
2867         return;
2868 
2869     PVMFJitterBufferNodeCommand aCmd = iCurrentCommand.front();
2870     if (iJitterBufferState == PVMF_JITTER_BUFFER_READY)
2871     {
2872         switch (iInterfaceState)
2873         {
2874             case EPVMFNodePrepared:
2875             case EPVMFNodePaused:
2876             case EPVMFNodeStarted:
2877             {
2878                 /* transition to Started */
2879                 oStartPending = false;
2880                 SetState(EPVMFNodeStarted);
2881                 /* Enable Output Ports */
2882                 StartOutputPorts();
2883                 /* Enable remote activity monitoring */
2884                 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
2885                 for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
2886                 {
2887                     PVMFJitterBufferPortParams* pPortParams = *it;
2888                     if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
2889                     {
2890                         pPortParams->iMonitorForRemoteActivity = true;
2891                     }
2892                 }
2893                 CommandComplete(aCmd, PVMFSuccess);
2894                 /* Erase the command from the current queue */
2895                 iCurrentCommand.Erase(&iCurrentCommand.front());
2896             }
2897             break;
2898 
2899             default:
2900             {
2901                 SetState(EPVMFNodeError);
2902                 CommandComplete(aCmd, PVMFErrInvalidState);
2903                 /* Erase the command from the current queue */
2904                 iCurrentCommand.Erase(&iCurrentCommand.front());
2905             }
2906             break;
2907         }
2908     }
2909     else
2910     {
2911         SetState(EPVMFNodeError);
2912         CommandComplete(aCmd, PVMFErrInvalidState);
2913         /* Erase the command from the current queue */
2914         iCurrentCommand.Erase(&iCurrentCommand.front());
2915     }
2916 }
2917 
CancelStart()2918 void PVMFJitterBufferNode::CancelStart()
2919 {
2920     if (ipJitterBufferMisc)
2921         ipJitterBufferMisc->Reset();
2922 
2923     PVMFJitterBufferNodeCommand aCmd = iCurrentCommand.front();
2924     oStartPending = false;
2925     CommandComplete(aCmd, PVMFErrCancelled);
2926     /* Erase the command from the current queue */
2927     iCurrentCommand.Erase(&iCurrentCommand.front());
2928     return;
2929 }
2930 
DoStop(PVMFJitterBufferNodeCommand & aCmd)2931 void PVMFJitterBufferNode::DoStop(PVMFJitterBufferNodeCommand& aCmd)
2932 {
2933     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::DoStop"));
2934     LogSessionDiagnostics();
2935     PVMFStatus aStatus = PVMFSuccess;
2936 
2937     switch (iInterfaceState)
2938     {
2939         case EPVMFNodeStarted:
2940         case EPVMFNodePaused:
2941         {
2942             if (ipJitterBufferMisc)
2943                 ipJitterBufferMisc->StreamingSessionStopped();
2944 
2945             /* Clear queued messages in ports */
2946             for (uint32 i = 0; i < iPortVector.size(); i++)
2947             {
2948                 PVMFJitterBufferPortParams* pPortParams = NULL;
2949                 bool bRet = getPortContainer(iPortVector[i], pPortParams);
2950                 if (bRet)
2951                 {
2952                     if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
2953                     {
2954                         pPortParams->ipJitterBuffer->ResetJitterBuffer();
2955                     }
2956                     pPortParams->ResetParams();
2957                 }
2958                 iPortVector[i]->ClearMsgQueues();
2959             }
2960 
2961             if (aStatus == PVMFSuccess)
2962             {
2963                 /* Reset State Variables */
2964                 iDelayEstablished = false;
2965                 if (ipJitterBufferMisc)
2966                     ipJitterBufferMisc->SetSessionDurationExpired();
2967                 oStopOutputPorts = true;
2968                 oStartPending = false;
2969                 iJitterBufferState = PVMF_JITTER_BUFFER_READY;
2970                 iJitterDelayPercent = 0;
2971 
2972                 /* transition to Prepared state */
2973                 SetState(EPVMFNodePrepared);
2974             }
2975             CommandComplete(iInputCommands, aCmd, aStatus);
2976         }
2977 
2978         break;
2979 
2980         default:
2981             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
2982             break;
2983     }
2984 }
2985 
2986 /**
2987  * Called by the command handler AO to do the node Flush
2988  */
DoFlush(PVMFJitterBufferNodeCommand & aCmd)2989 void PVMFJitterBufferNode::DoFlush(PVMFJitterBufferNodeCommand& aCmd)
2990 {
2991     OSCL_UNUSED_ARG(aCmd);
2992 }
2993 
2994 /**
2995  * Called by the command handler AO to do the node Pause
2996  */
DoPause(PVMFJitterBufferNodeCommand & aCmd)2997 void PVMFJitterBufferNode::DoPause(PVMFJitterBufferNodeCommand& aCmd)
2998 {
2999     iPauseTime = 0;
3000     switch (iInterfaceState)
3001     {
3002         case EPVMFNodeStarted:
3003         case EPVMFNodePaused:
3004         {
3005             uint32 currticks = OsclTickCount::TickCount();
3006             iPauseTime = OsclTickCount::TicksToMsec(currticks);
3007             ipJitterBufferMisc->StreamingSessionPaused();
3008             SetState(EPVMFNodePaused);
3009             StopOutputPorts();
3010             CancelEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
3011             CancelEventCallBack(JB_NOTIFY_REPORT_BUFFERING_STATUS);
3012             PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoPause Success"));
3013             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
3014         }
3015         break;
3016 
3017         default:
3018             PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::DoPause PVMFErrInvalidState iInterfaceState %d", iInterfaceState));
3019             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
3020             break;
3021     }
3022 }
3023 
3024 /**
3025  * Called by the command handler AO to do the node Reset.
3026  */
DoReset(PVMFJitterBufferNodeCommand & aCmd)3027 void PVMFJitterBufferNode::DoReset(PVMFJitterBufferNodeCommand& aCmd)
3028 {
3029     PVMF_JBNODE_LOGERROR((0, "JitterBufferNode:DoReset %d", iInterfaceState));
3030     LogSessionDiagnostics();
3031     ResetNodeParams();
3032     SetState(EPVMFNodeIdle);
3033     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
3034 }
3035 
3036 /**
3037  * Called by the command handler AO to do the Cancel single command
3038  */
DoCancelCommand(PVMFJitterBufferNodeCommand & aCmd)3039 void PVMFJitterBufferNode::DoCancelCommand(PVMFJitterBufferNodeCommand& aCmd)
3040 {
3041     /* extract the command ID from the parameters.*/
3042     PVMFCommandId id;
3043     aCmd.PVMFJitterBufferNodeCommandBase::Parse(id);
3044 
3045     /* first check "current" command if any */
3046     {
3047         PVMFJitterBufferNodeCommand* cmd = iCurrentCommand.FindById(id);
3048         if (cmd)
3049         {
3050             /* cancel the queued command */
3051             CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
3052             /* report cancel success */
3053             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
3054             return;
3055         }
3056     }
3057 
3058     /* next check input queue */
3059     {
3060         /* start at element 1 since this cancel command is element 0 */
3061         PVMFJitterBufferNodeCommand* cmd = iInputCommands.FindById(id, 1);
3062         if (cmd)
3063         {
3064             /* cancel the queued command */
3065             CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
3066             /* report cancel success */
3067             CommandComplete(iInputCommands, aCmd, PVMFSuccess);
3068             return;
3069         }
3070     }
3071     /* if we get here the command isn't queued so the cancel fails */
3072     CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
3073 }
3074 
3075 /**
3076  * Called by the command handler AO to do the Cancel All
3077  */
DoCancelAllCommands(PVMFJitterBufferNodeCommand & aCmd)3078 void PVMFJitterBufferNode::DoCancelAllCommands(PVMFJitterBufferNodeCommand& aCmd)
3079 {
3080     /* first cancel the current command if any */
3081     if (!iCurrentCommand.empty())
3082     {
3083         if (iCurrentCommand.front().iCmd == PVMF_JITTER_BUFFER_NODE_PREPARE)
3084         {
3085             CancelPrepare();
3086         }
3087         else if (iCurrentCommand.front().iCmd == PVMF_JITTER_BUFFER_NODE_START)
3088         {
3089             CancelStart();
3090         }
3091         else
3092         {
3093             OSCL_ASSERT(false);
3094         }
3095     }
3096     /* next cancel all queued commands */
3097     {
3098         /* start at element 1 since this cancel command is element 0. */
3099         while (iInputCommands.size() > 1)
3100             CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
3101     }
3102 
3103     uint32 i;
3104     for (i = 0; i < iPortVector.size(); i++)
3105     {
3106         PVMFJitterBufferPortParams* pPortParams = NULL;
3107         bool bRet = getPortContainer(iPortVector[i], pPortParams);
3108         if (bRet)
3109         {
3110             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
3111             {
3112                 pPortParams->ipJitterBuffer->ResetJitterBuffer();
3113             }
3114             pPortParams->ResetParams();
3115         }
3116         iPortVector[i]->ClearMsgQueues();
3117     }
3118 
3119 
3120     /* finally, report cancel complete.*/
3121     CommandComplete(iInputCommands, aCmd, PVMFSuccess);
3122 }
3123 
3124 PVMFPortInterface*
getPortCounterpart(PVMFPortInterface * aPort)3125 PVMFJitterBufferNode::getPortCounterpart(PVMFPortInterface* aPort)
3126 {
3127     uint32 ii;
3128     /*
3129      * Get port params
3130      */
3131     for (ii = 0; ii < iPortParamsQueue.size(); ii++)
3132     {
3133         if (&iPortParamsQueue[ii]->irPort == aPort)
3134         {
3135             break;
3136         }
3137     }
3138     if (ii >= iPortParamsQueue.size())
3139     {
3140         return NULL;
3141     }
3142 
3143     PVMFJitterBufferNodePortTag tag = iPortParamsQueue[ii]->iTag;
3144     int32 id = iPortParamsQueue[ii]->iId;
3145     uint32 jj;
3146 
3147     /* Even numbered ports are input ports */
3148     if (tag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
3149     {
3150         for (jj = 0; jj < iPortParamsQueue.size(); jj++)
3151         {
3152             if ((id + 1) == iPortParamsQueue[jj]->iId)
3153             {
3154                 return (&iPortParamsQueue[jj]->irPort);
3155             }
3156         }
3157     }
3158     /* odd numbered ports are output ports */
3159     else if (tag == PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT)
3160     {
3161         for (jj = 0; jj < iPortParamsQueue.size(); jj++)
3162         {
3163             if ((id - 1) == iPortParamsQueue[jj]->iId)
3164             {
3165                 return (&iPortParamsQueue[jj]->irPort);
3166 
3167 
3168             }
3169         }
3170     }
3171     return NULL;
3172 }
3173 
3174 
3175 
3176 
3177 ///////////////////////////////////////////////////////////////////////////////
3178 //Jitter Buffer Extension Interface Implementation
3179 ///////////////////////////////////////////////////////////////////////////////
3180 
3181 ///////////////////////////////////////////////////////////////////////////////
3182 //OsclActiveObject
3183 ///////////////////////////////////////////////////////////////////////////////
3184 
3185 
3186 ///////////////////////////////////////////////////////////////////////////////
3187 //PVMFJitterBufferObserver Implementation
3188 ///////////////////////////////////////////////////////////////////////////////
JitterBufferFreeSpaceAvailable(OsclAny * aContext)3189 void PVMFJitterBufferNode::JitterBufferFreeSpaceAvailable(OsclAny* aContext)
3190 {
3191     PVMFPortInterface* port = OSCL_STATIC_CAST(PVMFPortInterface*, aContext);
3192     PVMFJitterBufferPort* jbPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, port);
3193     PVMFJitterBufferPortParams* portParams = jbPort->iPortParams;
3194     if (portParams)
3195         portParams->iProcessIncomingMessages = true;
3196 
3197     if (IsAdded())
3198     {
3199         RunIfNotReady();
3200     }
3201 }
3202 
ProcessJBInfoEvent(PVMFAsyncEvent & aEvent)3203 void PVMFJitterBufferNode::ProcessJBInfoEvent(PVMFAsyncEvent& aEvent)
3204 {
3205     PVMF_JBNODE_LOGCLOCK_REBUFF((0, "PVMFJitterBufferNode::ProcessJBInfoEvent: Event Type [%d]", aEvent.GetEventType()));
3206     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::ProcessJBInfoEvent Event: Type [%d]", aEvent.GetEventType()));
3207     switch (aEvent.GetEventType())
3208     {
3209         case PVMFInfoUnderflow:
3210         {
3211             RequestEventCallBack(JB_NOTIFY_REPORT_BUFFERING_STATUS);
3212             if (oStartPending == false)
3213             {
3214                 UpdateRebufferingStats(PVMFInfoUnderflow);
3215                 ipJitterBufferMisc->StreamingSessionBufferingStart();
3216                 ReportInfoEvent(PVMFInfoUnderflow);
3217                 ReportInfoEvent(PVMFInfoBufferingStart);
3218                 ReportInfoEvent(PVMFInfoBufferingStatus);
3219             }
3220         }
3221         break;
3222         case PVMFInfoDataReady:
3223         {
3224             UpdateRebufferingStats(PVMFInfoDataReady);
3225             ReportInfoEvent(PVMFInfoBufferingStatus);
3226             ReportInfoEvent(PVMFInfoDataReady);
3227             ReportInfoEvent(PVMFInfoBufferingComplete);
3228             CancelEventCallBack(JB_NOTIFY_REPORT_BUFFERING_STATUS);
3229 
3230             Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
3231             for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
3232             {
3233                 PVMFJitterBufferPortParams* pPortParams = *it;
3234                 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
3235                 {
3236                     pPortParams->iCanReceivePktFromJB = true;
3237                     pPortParams->ipJitterBuffer->CancelNotifyCanRetrievePacket();
3238                     PVMFJitterBufferStats stats = pPortParams->ipJitterBuffer->getJitterBufferStats();
3239                     PVMF_JBNODE_LOGDATATRAFFIC((0, "Mime %s stats.currentOccupancy[%d], stats.maxSeqNumRegistered[%d], stats.lastRetrievedSeqNum[%d] stats.maxTimeStampRetrievedWithoutRTPOffset[%d]", pPortParams->iMimeType.get_cstr(), stats.currentOccupancy, stats.maxSeqNumRegistered, stats.lastRetrievedSeqNum, stats.maxTimeStampRetrievedWithoutRTPOffset));
3240                 }
3241             }
3242 
3243             if (oStartPending)
3244             {
3245                 CompleteStart();
3246             }
3247             else
3248             {
3249                 ipJitterBufferMisc->StreamingSessionBufferingEnd();
3250 
3251             }
3252         }
3253         break;
3254         case PVMFInfoOverflow:
3255         {
3256             ReportInfoEvent(PVMFInfoOverflow);
3257         }
3258         break;
3259         case PVMFJitterBufferNodeJitterBufferLowWaterMarkReached:
3260         {
3261             Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
3262             for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end(); iter++)
3263             {
3264                 PVMFJitterBufferPortParams* pPortParams = *iter;
3265                 if (pPortParams->iMonitorForRemoteActivity == false)
3266                 {
3267                     pPortParams->iMonitorForRemoteActivity = true;
3268                     RequestEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
3269                 }
3270 
3271             }
3272             ReportInfoEvent(PVMFJitterBufferNodeJitterBufferLowWaterMarkReached);
3273         }
3274         break;
3275         case PVMFJitterBufferNodeJitterBufferHighWaterMarkReached:
3276         {
3277             Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
3278             for (iter = iPortParamsQueue.begin(); iter != iPortParamsQueue.end(); iter++)
3279             {
3280                 PVMFJitterBufferPortParams* pPortParams = *iter;
3281                 if (pPortParams->iMonitorForRemoteActivity == true)
3282                 {
3283                     pPortParams->iMonitorForRemoteActivity = false;
3284                     CancelEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
3285                 }
3286             }
3287             ReportInfoEvent(PVMFJitterBufferNodeJitterBufferHighWaterMarkReached);
3288         }
3289         break;
3290         case PVMFJitterBufferNodeStreamThinningRecommended:
3291         {
3292             PVMFNodeInterface::ReportInfoEvent(aEvent);
3293         }
3294         break;
3295         default:
3296         {
3297             //noop
3298         }
3299     }
3300 
3301 }
3302 
PacketReadyToBeRetrieved(OsclAny * aContext)3303 void PVMFJitterBufferNode::PacketReadyToBeRetrieved(OsclAny* aContext)
3304 {
3305     if (aContext)
3306     {
3307         PVMFJitterBufferPort* port = OSCL_REINTERPRET_CAST(PVMFJitterBufferPort*, aContext);
3308         PVMFJitterBufferPortParams* portparams = port->GetPortParams();
3309         if (portparams)
3310         {
3311             PVMF_JBNODE_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferNode::PacketReadyToBeRetrieved for mime type %s", portparams->iMimeType.get_cstr()));
3312             portparams->iCanReceivePktFromJB = true;
3313         }
3314     }
3315 }
3316 
EndOfStreamSignalled(OsclAny * aContext)3317 void PVMFJitterBufferNode::EndOfStreamSignalled(OsclAny* aContext)
3318 {
3319     if (aContext)
3320     {
3321         PVLogger* ipDataPathLoggerRTCP = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.rtcp");
3322         PVMF_JBNODE_LOG_RTCP_DATAPATH((0, "PVMFJitterBufferNode::EndOfStreamSignalled"));
3323         PVMFJitterBufferPort* port = OSCL_REINTERPRET_CAST(PVMFJitterBufferPort*, aContext);
3324         PVMFJitterBufferPortParams* portparams = port->GetPortParams();
3325         if (portparams)
3326         {
3327             RunIfNotReady();
3328         }
3329     }
3330 }
3331 
UpdateRebufferingStats(PVMFEventType aEventType)3332 void PVMFJitterBufferNode::UpdateRebufferingStats(PVMFEventType aEventType)
3333 {
3334     if (aEventType == PVMFInfoUnderflow)
3335     {
3336         Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
3337         for (it = iPortParamsQueue.begin();
3338                 it != iPortParamsQueue.end();
3339                 it++)
3340         {
3341             PVMFJitterBufferPortParams* pJitterBufferPortParams = *it;
3342             if (pJitterBufferPortParams->iMonitorForRemoteActivity == false)
3343             {
3344                 pJitterBufferPortParams->iMonitorForRemoteActivity = true;
3345                 CancelEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
3346                 RequestEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
3347             }
3348         }
3349 
3350         PVMF_JBNODE_LOGDATATRAFFIC_FLOWCTRL_E((0, "PVMFJitterBufferNode::UpdateRebufferingStats: Sending Auto Resume"));
3351     }
3352 
3353 }
3354 ///////////////////////////////////////////////////////////////////////////////
3355 //PVMFJitterBufferMiscObserver
3356 ///////////////////////////////////////////////////////////////////////////////
MessageReadyToSend(PVMFPortInterface * & aPort,PVMFSharedMediaMsgPtr & aMessage)3357 void PVMFJitterBufferNode::MessageReadyToSend(PVMFPortInterface*& aPort, PVMFSharedMediaMsgPtr& aMessage)
3358 {
3359     PVMF_JBNODE_LOGINFO((0, "0x%x PVMFJitterBufferNode::MessageReadyToSend: aPort=0x%x", this, aPort));
3360 
3361     PVMFJitterBufferPort* jitterbufferPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, aPort);
3362 
3363     //Kind of messages received here
3364     //RTCP reports
3365     //Firewall packets
3366     //We do not expect port to go in busy state at firewall port and if somehow port used for sending rtcp messages
3367     //is in busy state, or gets into busy state, we just ignore it and discard the message
3368     PVMFStatus status = PVMFSuccess;
3369     aPort->QueueOutgoingMsg(aMessage);
3370     status = aPort->Send();
3371     if (status == PVMFSuccess)
3372     {
3373         jitterbufferPort->iPortParams->iNumMediaMsgsSent++;
3374     }
3375     return;
3376 }
3377 
MediaReceivingChannelPrepared(bool aStatus)3378 void PVMFJitterBufferNode::MediaReceivingChannelPrepared(bool aStatus)
3379 {
3380     //ignore the status param.
3381     OSCL_UNUSED_ARG(aStatus);
3382     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode::MediaRecvChannelPrerared In"));
3383     iMediaReceiveingChannelPrepared = true;
3384     if (iCurrentCommand.size())
3385     {
3386         PVMFJitterBufferNodeCommand& cmd = iCurrentCommand.front();
3387         if (PVMF_JITTER_BUFFER_NODE_PREPARE == cmd.iCmd)
3388         {
3389             CompletePrepare();
3390         }
3391         if (PVMF_JITTER_BUFFER_NODE_START == cmd.iCmd)
3392         {
3393             CompleteStart();
3394         }
3395     }
3396 }
3397 
ProcessRTCPControllerEvent(PVMFAsyncEvent & aEvent)3398 void PVMFJitterBufferNode::ProcessRTCPControllerEvent(PVMFAsyncEvent& aEvent)
3399 {
3400     PVMFNodeInterface::ReportInfoEvent(aEvent);
3401 }
3402 
SessionSessionExpired()3403 void PVMFJitterBufferNode::SessionSessionExpired()
3404 {
3405 
3406     CancelEventCallBack(JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED);
3407 }
3408 
3409 ///////////////////////////////////////////////////////////////////////////////
3410 //PVMFJBEventNotifierObserver implementation
3411 ///////////////////////////////////////////////////////////////////////////////
ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType,uint32 aCallBkId,const OsclAny * aContext,PVMFStatus aStatus)3412 void PVMFJitterBufferNode::ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType, uint32 aCallBkId, const OsclAny* aContext, PVMFStatus aStatus)
3413 {
3414     OSCL_UNUSED_ARG(aClockNotificationInterfaceType);
3415     OSCL_UNUSED_ARG(aContext);
3416     PVMF_JBNODE_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::ProcessCallBack In CallBackId [%d] ", aCallBkId));
3417 
3418     if (PVMFSuccess == aStatus)
3419     {
3420         if (aCallBkId == iIncomingMediaInactivityDurationCallBkId)
3421         {
3422             iIncomingMediaInactivityDurationCallBkPending = false;
3423             HandleEvent_IncomingMediaInactivityDurationExpired();
3424         }
3425         else if (aCallBkId == iNotifyBufferingStatusCallBkId)
3426         {
3427             iNotifyBufferingStatusCallBkPending = false;
3428             HandleEvent_NotifyReportBufferingStatus();
3429         }
3430     }
3431     else
3432     {
3433 
3434         //Log it
3435     }
3436     PVMF_JBNODE_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::ProcessCallBack Out"));
3437 }
3438 
HandleEvent_IncomingMediaInactivityDurationExpired()3439 void PVMFJitterBufferNode::HandleEvent_IncomingMediaInactivityDurationExpired()
3440 {
3441     PVMF_JBNODE_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::HandleEvent_IncomingMediaInactivityDurationExpired In"));
3442 
3443     PVUuid eventuuid = PVMFJitterBufferNodeEventTypeUUID;
3444     int32 errcode = PVMFJitterBufferNodeRemoteInactivityTimerExpired;
3445 
3446     PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::HandleEvent_IncomingMediaInactivityDurationExpired- iCurrentCommand.size()[%d]", iCurrentCommand.size()));
3447     if (iCurrentCommand.size() > 0)
3448     {
3449         PVMFJitterBufferNodeCommand cmd = iCurrentCommand.front();
3450         CommandComplete(cmd, PVMFFailure, NULL, &eventuuid, &errcode);
3451         iCurrentCommand.Erase(&iCurrentCommand.front());
3452     }
3453     else
3454     {
3455         ReportInfoEvent(PVMFErrTimeout, NULL, &eventuuid, &errcode);
3456         ipJitterBufferMisc->SetSessionDurationExpired();
3457         if (IsAdded())
3458         {
3459             RunIfNotReady();
3460         }
3461     }
3462 
3463     PVMF_JBNODE_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::HandleEvent_IncomingMediaInactivityDurationExpired Out"));
3464 }
3465 
HandleEvent_NotifyReportBufferingStatus()3466 void PVMFJitterBufferNode::HandleEvent_NotifyReportBufferingStatus()
3467 {
3468     PVMF_JBNODE_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::HandleEvent_NotifyReportBufferingStatus In"));
3469     if (iDelayEstablished == false)
3470     {
3471         /*
3472          * Check to see if the session duration has expired
3473          */
3474         if (ipJitterBufferMisc->IsSessionExpired())
3475         {
3476             PVMF_JBNODE_LOGCLOCK((0, "PVMFJitterBufferNode::TimeoutOccurred - Session Duration Expired"));
3477             /* Force out of rebuffering */
3478             Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
3479             for (it = iPortParamsQueue.begin();
3480                     it != iPortParamsQueue.end();
3481                     it++)
3482             {
3483                 PVMFJitterBufferPortParams* pPortParams = *it;
3484                 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
3485                 {
3486                     SendData(&(pPortParams->irPort));
3487                 }
3488             }
3489             if (IsAdded())
3490             {
3491                 RunIfNotReady();
3492             }
3493         }
3494         else
3495         {
3496             ReportInfoEvent(PVMFInfoBufferingStatus);
3497             RequestEventCallBack(JB_NOTIFY_REPORT_BUFFERING_STATUS);
3498         }
3499     }
3500     PVMF_JBNODE_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::HandleEvent_NotifyReportBufferingStatus Out"));
3501 }
3502 
3503 ///////////////////////////////////////////////////////////////////////////////
3504 //Utility functions
3505 ///////////////////////////////////////////////////////////////////////////////
3506 
3507 bool
getPortContainer(PVMFPortInterface * aPort,PVMFJitterBufferPortParams * & aPortParamsPtr)3508 PVMFJitterBufferNode::getPortContainer(PVMFPortInterface* aPort,
3509                                        PVMFJitterBufferPortParams*& aPortParamsPtr)
3510 {
3511     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
3512 
3513     for (it = iPortParamsQueue.begin();
3514             it != iPortParamsQueue.end();
3515             it++)
3516     {
3517         PVMFJitterBufferPortParams* pPortParams = *it;
3518         if (&pPortParams->irPort == aPort)
3519         {
3520             aPortParamsPtr = *it;
3521             return true;
3522         }
3523     }
3524     return false;
3525 }
3526 
RequestEventCallBack(JB_NOTIFY_CALLBACK aEventType,uint32 aDelay,OsclAny * aContext)3527 bool PVMFJitterBufferNode::RequestEventCallBack(JB_NOTIFY_CALLBACK aEventType, uint32 aDelay, OsclAny* aContext)
3528 {
3529     OSCL_UNUSED_ARG(aDelay);
3530     OSCL_UNUSED_ARG(aContext);
3531     bool retval = false;
3532     switch (aEventType)
3533     {
3534         case JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED:
3535         {
3536             PVMFJBEventNotificationRequestInfo eventRequestInfo(CLOCK_NOTIFICATION_INTF_TYPE_NONDECREASING, this, NULL);
3537             retval = ipEventNotifier->RequestCallBack(eventRequestInfo, iMaxInactivityDurationForMediaInMs, iIncomingMediaInactivityDurationCallBkId);
3538             if (retval)
3539             {
3540                 iIncomingMediaInactivityDurationCallBkPending = true;
3541             }
3542         }
3543         break;
3544         case JB_NOTIFY_REPORT_BUFFERING_STATUS:
3545         {
3546             if (iNotifyBufferingStatusCallBkPending)
3547             {
3548                 CancelEventCallBack(JB_NOTIFY_REPORT_BUFFERING_STATUS);
3549             }
3550             PVMFJBEventNotificationRequestInfo eventRequestInfo(CLOCK_NOTIFICATION_INTF_TYPE_NONDECREASING, this, NULL);
3551             retval = ipEventNotifier->RequestCallBack(eventRequestInfo, iBufferingStatusIntervalInMs, iNotifyBufferingStatusCallBkId);
3552             if (retval)
3553             {
3554                 iNotifyBufferingStatusCallBkPending = true;
3555             }
3556         }
3557         break;
3558 
3559         default:
3560         {
3561             //Log it
3562         }
3563     }
3564     return retval;
3565 }
3566 
CancelEventCallBack(JB_NOTIFY_CALLBACK aEventType,OsclAny * aContext)3567 void PVMFJitterBufferNode::CancelEventCallBack(JB_NOTIFY_CALLBACK aEventType, OsclAny* aContext)
3568 {
3569     OSCL_UNUSED_ARG(aContext);
3570     switch (aEventType)
3571     {
3572         case JB_INCOMING_MEDIA_INACTIVITY_DURATION_EXPIRED:
3573         {
3574             if (iIncomingMediaInactivityDurationCallBkPending)
3575             {
3576                 PVMFJBEventNotificationRequestInfo eventRequestInfo(CLOCK_NOTIFICATION_INTF_TYPE_NONDECREASING, this, NULL);
3577                 ipEventNotifier->CancelCallBack(eventRequestInfo, iIncomingMediaInactivityDurationCallBkId);
3578                 iIncomingMediaInactivityDurationCallBkPending = false;
3579             }
3580         }
3581         break;
3582         case JB_NOTIFY_REPORT_BUFFERING_STATUS:
3583         {
3584             if (iNotifyBufferingStatusCallBkPending)
3585             {
3586                 PVMFJBEventNotificationRequestInfo eventRequestInfo(CLOCK_NOTIFICATION_INTF_TYPE_NONDECREASING, this, NULL);
3587                 ipEventNotifier->CancelCallBack(eventRequestInfo, iNotifyBufferingStatusCallBkId);
3588                 iNotifyBufferingStatusCallBkPending = false;
3589             }
3590         }
3591         break;
3592 
3593         default:
3594         {
3595             //Log it
3596         }
3597     }
3598     return;
3599 }
3600 
SetState(TPVMFNodeInterfaceState s)3601 void PVMFJitterBufferNode::SetState(TPVMFNodeInterfaceState s)
3602 {
3603     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode:SetState %d", s));
3604     PVMFNodeInterface::SetState(s);
3605 }
3606 
ReportErrorEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)3607 void PVMFJitterBufferNode::ReportErrorEvent(PVMFEventType aEventType,
3608         OsclAny* aEventData,
3609         PVUuid* aEventUUID,
3610         int32* aEventCode)
3611 {
3612     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode:NodeErrorEvent Type %d Data %d"
3613                           , aEventType, aEventData));
3614 
3615     if (aEventUUID && aEventCode)
3616     {
3617         PVMFBasicErrorInfoMessage* eventmsg;
3618         PVMF_JITTER_BUFFER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), eventmsg);
3619         PVMFAsyncEvent asyncevent(PVMFErrorEvent,
3620                                   aEventType,
3621                                   NULL,
3622                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
3623                                   aEventData,
3624                                   NULL,
3625                                   0);
3626         PVMFNodeInterface::ReportErrorEvent(asyncevent);
3627         eventmsg->removeRef();
3628     }
3629     else
3630     {
3631         PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
3632     }
3633 }
3634 
ReportInfoEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)3635 void PVMFJitterBufferNode::ReportInfoEvent(PVMFEventType aEventType,
3636         OsclAny* aEventData,
3637         PVUuid* aEventUUID,
3638         int32* aEventCode)
3639 {
3640     PVMF_JBNODE_LOGINFO((0, "PVMFJitterBufferNode:NodeInfoEvent Type %d Data %d"
3641                          , aEventType, aEventData));
3642 
3643     if (aEventType == PVMFInfoBufferingStatus)
3644     {
3645         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
3646                                   aEventType,
3647                                   NULL,
3648                                   NULL,
3649                                   aEventData,
3650                                   &iJitterDelayPercent,
3651                                   sizeof(iJitterDelayPercent));
3652         PVMFNodeInterface::ReportInfoEvent(asyncevent);
3653     }
3654     else if (aEventUUID && aEventCode)
3655     {
3656         PVMFBasicErrorInfoMessage* eventmsg;
3657         PVMF_JITTER_BUFFER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), eventmsg);
3658         PVMFErrorInfoMessageInterface* interimPtr =
3659             OSCL_STATIC_CAST(PVMFErrorInfoMessageInterface*, eventmsg);
3660         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
3661                                   aEventType,
3662                                   NULL,
3663                                   OSCL_STATIC_CAST(PVInterface*, interimPtr),
3664                                   aEventData,
3665                                   NULL,
3666                                   0);
3667         PVMFNodeInterface::ReportInfoEvent(asyncevent);
3668         eventmsg->removeRef();
3669     }
3670     else
3671     {
3672         PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
3673     }
3674 }
3675 
3676 PVMFJitterBuffer*
findJitterBuffer(PVMFPortInterface * aPort)3677 PVMFJitterBufferNode::findJitterBuffer(PVMFPortInterface* aPort)
3678 {
3679     uint32 ii;
3680     for (ii = 0; ii < iPortParamsQueue.size(); ii++)
3681     {
3682 
3683         if (&iPortParamsQueue[ii]->irPort == aPort)
3684         {
3685             return (iPortParamsQueue[ii]->ipJitterBuffer);
3686 
3687         }
3688     }
3689     return NULL;
3690 }
3691 
3692 
LogSessionDiagnostics()3693 void PVMFJitterBufferNode::LogSessionDiagnostics()
3694 {
3695     if (iDiagnosticsLogged == false)
3696     {
3697         ipDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.streamingmanager");
3698 
3699         LogPortDiagnostics();
3700 
3701         Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
3702         for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
3703         {
3704             PVMFJitterBufferPortParams* pPortParams = *it;
3705             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
3706             {
3707                 PVMFJitterBuffer* jitterBuffer = findJitterBuffer(&pPortParams->irPort);
3708                 if (jitterBuffer != NULL)
3709                 {
3710                     PVMFJitterBufferStats jbStats = jitterBuffer->getJitterBufferStats();
3711                     uint32 in_wrap_count = 0;
3712                     uint32 max_ts_reg = jbStats.maxTimeStampRegistered;
3713                     pPortParams->iMediaClockConverter.set_clock(max_ts_reg, in_wrap_count);
3714 
3715                     in_wrap_count = 0;
3716                     uint32 max_ts_ret = jbStats.maxTimeStampRetrieved;
3717                     pPortParams->iMediaClockConverter.set_clock(max_ts_ret, in_wrap_count);
3718 
3719                     uint32 currentTime32 = 0;
3720                     uint32 currentTimeBase32 = 0;
3721                     bool overflowFlag = false;
3722                     ipJitterBufferMisc->GetEstimatedServerClock().GetCurrentTime32(currentTime32,
3723                             overflowFlag,
3724                             PVMF_MEDIA_CLOCK_MSEC,
3725                             currentTimeBase32);
3726                     uint32 bitrate32 = 0;
3727                     uint32 totalNumBytesRecvd = jbStats.totalNumBytesRecvd;
3728                     if (currentTime32 != 0)
3729                     {
3730                         bitrate32 = (totalNumBytesRecvd / currentTime32);
3731                     }
3732 
3733                     bitrate32 *= 8;
3734 
3735                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3736                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "JitterBuffer - TrackMime Type = %s", pPortParams->iMimeType.get_cstr()));
3737                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "Total Num Packets Recvd = %d", jbStats.totalNumPacketsReceived));
3738                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "Total Num Packets Registered Into JitterBuffer = %d", jbStats.totalNumPacketsRegistered));
3739                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "Total Num Packets Retrieved From JitterBuffer = %d", jbStats.totalNumPacketsRetrieved));
3740                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "MaxSeqNum Recvd = %d", jbStats.maxSeqNumReceived));
3741                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "MaxSeqNum Registered = %d", jbStats.maxSeqNumRegistered));
3742                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "MaxSeqNum Retrieved = %d", jbStats.lastRetrievedSeqNum));
3743                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "MaxTimeStamp Registered In MS = %d", pPortParams->iMediaClockConverter.get_converted_ts(1000)));
3744                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "MaxTimeStamp Retrieved In MS = %d", pPortParams->iMediaClockConverter.get_converted_ts(1000)));
3745                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "Total Number of Packets Lost = %d", jbStats.totalPacketsLost));
3746                     PVMF_JBNODE_LOGDIAGNOSTICS((0, "Estimated Bitrate = %d", bitrate32));
3747                 }
3748             }
3749         }
3750         iDiagnosticsLogged = true;
3751     }
3752 }
3753 
LogPortDiagnostics()3754 void PVMFJitterBufferNode::LogPortDiagnostics()
3755 {
3756     PVLogger* ipDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.streamingmanager");
3757 
3758     PVMF_JBNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3759     PVMF_JBNODE_LOGDIAGNOSTICS((0, "PVMFJitterBufferNode - iNumRunL = %d", iNumRunL));
3760 
3761     Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
3762     for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
3763     {
3764         PVMFJitterBufferPortParams* pPortParams = *it;
3765         PvmfPortBaseImpl* ptr =
3766             OSCL_STATIC_CAST(PvmfPortBaseImpl*, &pPortParams->irPort);
3767         PvmfPortBaseImplStats stats;
3768         ptr->GetStats(stats);
3769 
3770         if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
3771         {
3772             PVMF_JBNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3773             PVMF_JBNODE_LOGDIAGNOSTICS((0, "PVMF_JITTER_BUFFER_PORT_TYPE_INPUT"));
3774             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingMsgRecv = %d", stats.iIncomingMsgRecv));
3775             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingMsgConsumed = %d", stats.iIncomingMsgConsumed));
3776             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingQueueBusy = %d", stats.iIncomingQueueBusy));
3777             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgQueued = %d", stats.iOutgoingMsgQueued));
3778             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgSent = %d", stats.iOutgoingMsgSent));
3779             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingQueueBusy = %d", stats.iOutgoingQueueBusy));
3780             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgDiscarded = %d", stats.iOutgoingMsgDiscarded));
3781         }
3782         else if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK)
3783         {
3784             PVMF_JBNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3785             PVMF_JBNODE_LOGDIAGNOSTICS((0, "PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK"));
3786             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingMsgRecv = %d", stats.iIncomingMsgRecv));
3787             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingMsgConsumed = %d", stats.iIncomingMsgConsumed));
3788             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingQueueBusy = %d", stats.iIncomingQueueBusy));
3789             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgQueued = %d", stats.iOutgoingMsgQueued));
3790             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgSent = %d", stats.iOutgoingMsgSent));
3791             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingQueueBusy = %d", stats.iOutgoingQueueBusy));
3792             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgDiscarded = %d", stats.iOutgoingMsgDiscarded));
3793         }
3794         else if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT)
3795         {
3796             PVMF_JBNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3797             PVMF_JBNODE_LOGDIAGNOSTICS((0, "PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT"));
3798             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingMsgRecv = %d", stats.iIncomingMsgRecv));
3799             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingMsgConsumed = %d", stats.iIncomingMsgConsumed));
3800             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iIncomingQueueBusy = %d", stats.iIncomingQueueBusy));
3801             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgQueued = %d", stats.iOutgoingMsgQueued));
3802             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgSent = %d", stats.iOutgoingMsgSent));
3803             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingQueueBusy = %d", stats.iOutgoingQueueBusy));
3804             PVMF_JBNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgDiscarded = %d", stats.iOutgoingMsgDiscarded));
3805         }
3806     }
3807 }
3808 
PrepareForPlaylistSwitch()3809 bool PVMFJitterBufferNode::PrepareForPlaylistSwitch()
3810 {
3811 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
3812     uint32 clientClock32 = 0;
3813     bool overflowFlag = false;
3814     ipClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3815     uint32 serverClock32 = ipJitterBufferMisc->GetEstimatedServerClockValue();
3816     PVMF_JBNODE_LOGCLOCK_REBUFF((0, "PVMFJitterBufferNode::PrepareForPlaylistSwitch - Before - EstServClock=%d",
3817                                  serverClock32));
3818     PVMF_JBNODE_LOGCLOCK_REBUFF((0, "PVMFJitterBufferNode::PrepareForPlaylistSwitch - Before - ClientClock=%d",
3819                                  clientClock32));
3820 #endif
3821     iJitterBufferState = PVMF_JITTER_BUFFER_IN_TRANSITION;
3822     ipClientPlayBackClock->Pause();
3823 
3824     return true;
3825 }
3826 
ClockStateUpdated()3827 void PVMFJitterBufferNode::ClockStateUpdated()
3828 {
3829     PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ClockStateUpdated - iClientPlayBackClock[%d]", ipClientPlayBackClock->GetState()));
3830     if (!iDelayEstablished)
3831     {
3832         // Don't let anyone start the clock while
3833         // we're rebuffering
3834         if (ipClientPlayBackClock != NULL)
3835         {
3836             if (ipClientPlayBackClock->GetState() == PVMFMediaClock::RUNNING)
3837             {
3838                 PVMF_JBNODE_LOGERROR((0, "PVMFJitterBufferNode::ClockStateUpdated - Clock was started during rebuffering.  Pausing..."));
3839                 ipClientPlayBackClock->Pause();
3840             }
3841         }
3842     }
3843 }
3844 
NotificationsInterfaceDestroyed()3845 void PVMFJitterBufferNode::NotificationsInterfaceDestroyed()
3846 {
3847     //noop
3848 }
3849 
MediaTrackSSRCEstablished(PVMFJitterBuffer * aJitterBuffer,uint32 aSSRC)3850 void PVMFJitterBufferNode::MediaTrackSSRCEstablished(PVMFJitterBuffer* aJitterBuffer, uint32 aSSRC)
3851 {
3852     for (uint32 ii = 0; ii < iPortVector.size(); ii++)
3853     {
3854         PVMFJitterBufferPortParams* pPortParams = NULL;
3855         bool bRet = getPortContainer(iPortVector[ii], pPortParams);
3856         if (bRet)
3857         {
3858             if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT && pPortParams->ipJitterBuffer == aJitterBuffer)
3859             {
3860                 ipJitterBufferMisc->SetPortSSRC(&pPortParams->irPort, aSSRC);
3861                 break;
3862             }
3863         }
3864     }
3865 }
3866