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