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_jb_jitterbuffermisc.h"
20 #endif
21
22 #ifndef PVMF_SM_NODE_EVENTS_H_INCLUDED
23 #include "pvmf_sm_node_events.h"
24 #endif
25
26 #ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
27 #include "pvmf_basic_errorinfomessage.h"
28 #endif
29
New(PVMFJitterBufferMiscObserver * aObserver,PVMFMediaClock & aClientPlaybackClock,Oscl_Vector<PVMFJitterBufferPortParams *,OsclMemAllocator> & aPortParamsQueue)30 OSCL_EXPORT_REF PVMFJitterBufferMisc* PVMFJitterBufferMisc::New(PVMFJitterBufferMiscObserver* aObserver, PVMFMediaClock& aClientPlaybackClock, Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>& aPortParamsQueue)
31 {
32 int32 err = OsclErrNone;
33 PVMFJitterBufferMisc* ptr = NULL;
34 OSCL_TRY(err, ptr = OSCL_NEW(PVMFJitterBufferMisc, (aObserver, aClientPlaybackClock, aPortParamsQueue));
35 ptr->Construct());
36 if (err != OsclErrNone)
37 {
38 ptr = NULL;
39 }
40 return ptr;
41 }
42
Construct()43 void PVMFJitterBufferMisc::Construct()
44 {
45 ipJBEventsClockLogger = PVLogger::GetLoggerObject("jitterbuffernode.eventsclock");
46 ipRTCPDataPathLoggerIn = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.rtcp.in");
47 ipClockLoggerSessionDuration = PVLogger::GetLoggerObject("clock.streaming_manager.sessionduration");
48 ipClockLogger = PVLogger::GetLoggerObject("clock.jitterbuffernode");
49 ipDataPathLoggerIn = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.in");
50 ipDataPathLoggerOut = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.out");
51 ipDataPathLoggerRTCP = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.rtcp");
52 ipLogger = PVLogger::GetLoggerObject("PVMFJitterBufferMisc");
53 ipClockLoggerRebuff = PVLogger::GetLoggerObject("sourcenode.clock.rebuff");
54
55 CreateProtocolObjects();
56
57 ResetParams(false);
58
59 //Look for the input ports in the port vect
60 //Look for the corresponding input port and the jitter buffer associated with it
61 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter_begin = irPortParamsQueue.begin();
62 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter_end = irPortParamsQueue.end();
63 while (iter_begin != iter_end)
64 {
65 PVMFJitterBufferPortParams* portParams = *iter_begin;
66 if (PVMF_JITTER_BUFFER_PORT_TYPE_INPUT == portParams->iTag)//input port
67 {
68 PVMFPortInterface* feedbackPort = NULL;
69 PVMFJitterBuffer* jitterBuffer = NULL;
70 PVRTCPChannelController* rtcpChannelController = NULL;
71 if (LookupRTCPChannelParams(&portParams->irPort, feedbackPort, jitterBuffer))
72 {
73 rtcpChannelController = PVRTCPChannelController::New(ipRTCPProtoImplementator, *jitterBuffer, feedbackPort, irClientPlaybackClock, *ipWallClock);
74 ipRTCPProtoImplementator->AddPVRTCPChannelController(rtcpChannelController);
75 }
76 }
77 iter_begin++;
78 }
79 }
80
CreateProtocolObjects()81 bool PVMFJitterBufferMisc::CreateProtocolObjects()
82 {
83 uint32 start = 0;
84 bool overflowFlag = false;
85
86 ipEstimatedServerClock = OSCL_NEW(PVMFMediaClock, ());
87 ipEstimatedServerClock->SetClockTimebase(iEstimatedServerClockTimeBase);
88 if (ipEstimatedServerClock)
89 {
90 ipEstimatedServerClock->Stop();
91 ipEstimatedServerClock->SetStartTime32(start, PVMF_MEDIA_CLOCK_MSEC, overflowFlag);
92 }
93
94 ipWallClock = OSCL_NEW(PVMFMediaClock, ());
95 ipWallClock->SetClockTimebase(iWallClockTimeBase);
96 if (ipWallClock)
97 {
98 ipWallClock->SetStartTime32(start, PVMF_MEDIA_CLOCK_MSEC, overflowFlag);
99 }
100
101 ipNonDecreasingClock = OSCL_NEW(PVMFMediaClock, ());
102 ipNonDecreasingClock->SetClockTimebase(iNonDecreasingTimeBase);
103 if (ipNonDecreasingClock)
104 {
105 ipNonDecreasingClock->SetStartTime32(start, PVMF_MEDIA_CLOCK_MSEC, overflowFlag);
106 }
107
108 ipEventNotifier = PVMFJBEventNotifier::New(*ipNonDecreasingClock, irClientPlaybackClock, *ipEstimatedServerClock);
109
110 return true;
111 }
112
ResetParams(bool aReleaseMemory)113 void PVMFJitterBufferMisc::ResetParams(bool aReleaseMemory)
114 {
115 if (ipFireWallPacketExchangerImpl && aReleaseMemory)
116 {
117 OSCL_DELETE(ipFireWallPacketExchangerImpl);
118 }
119
120 ipFireWallPacketExchangerImpl = NULL;
121
122 iSessionDuration = 0;
123 iStreamingSessionExpired = false;
124 iPlayDurationAvailable = false;
125 iBroadcastSession = false;
126
127 iPlayStartTimeInMS = 0;
128 iPlayStopTimeInMS = 0;
129 iPlayStopTimeAvailable = false;
130
131
132 iFireWallPacketsExchangeEnabled = true;
133 iEstimatedServerClockUpdateCallbackId = 0;
134 iEstimatedServerClockUpdateCallbackPending = false;
135
136
137 }
138
~PVMFJitterBufferMisc()139 OSCL_EXPORT_REF PVMFJitterBufferMisc::~PVMFJitterBufferMisc()
140 {
141 ResetParams(true);
142 if (ipRTCPProtoImplementator)
143 {
144 ipRTCPProtoImplementator->RemoveAllRTCPChannelControllers();
145 OSCL_DELETE(ipRTCPProtoImplementator);
146 }
147
148 if (ipEventNotifier)
149 {
150 OSCL_DELETE(ipEventNotifier);
151 }
152
153 if (ipSessionDurationTimer)
154 {
155 OSCL_DELETE(ipSessionDurationTimer);
156 }
157
158 if (ipEstimatedServerClock)
159 {
160 OSCL_DELETE(ipEstimatedServerClock);
161 }
162
163 if (ipWallClock)
164 {
165 OSCL_DELETE(ipWallClock);
166 }
167
168 if (ipNonDecreasingClock)
169 {
170 OSCL_DELETE(ipNonDecreasingClock);
171 }
172 }
173
StreamingSessionStarted()174 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionStarted()
175 {
176 //if not already started...
177 if (ipNonDecreasingClock)
178 {
179 ipNonDecreasingClock->Start();
180 }
181
182 if (ipWallClock)
183 {
184 //Starts if not already running, check for state
185 ipWallClock->Start();
186 }
187
188 //Estimated server is to be updated only by the jitter buffer.
189 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
190 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
191 {
192 PVMFJitterBufferPortParams* pPortParam = *iter;
193 if (pPortParam)
194 {
195 PVMFJitterBuffer* jitterBuffer = pPortParam->ipJitterBuffer;
196 if (jitterBuffer)
197 {
198 jitterBuffer->StreamingSessionStarted();
199 }
200 }
201 }
202 }
203
StreamingSessionStopped()204 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionStopped()
205 {
206 Reset();
207 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
208 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
209 {
210 PVMFJitterBufferPortParams* pPortParam = *iter;
211 if (pPortParam)
212 {
213 PVMFJitterBuffer* jitterBuffer = pPortParam->ipJitterBuffer;
214 if (jitterBuffer)
215 {
216 jitterBuffer->StreamingSessionStopped();
217 }
218 }
219 }
220 }
221
StreamingSessionPaused()222 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionPaused()
223 {
224 ipNonDecreasingClock->Pause();
225 ipEstimatedServerClock->Pause();
226 if (ipSessionDurationTimer)
227 ipSessionDurationTimer->Cancel();
228
229 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
230 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
231 {
232 PVMFJitterBufferPortParams* pPortParam = *iter;
233 if (pPortParam)
234 {
235 PVMFJitterBuffer* jitterBuffer = pPortParam->ipJitterBuffer;
236 if (jitterBuffer)
237 {
238 jitterBuffer->StreamingSessionPaused();
239 }
240 }
241 }
242 }
243
StreamingSessionBufferingStart()244 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionBufferingStart()
245 {
246 if (ipSessionDurationTimer)
247 ipSessionDurationTimer->Cancel();
248 }
249
StreamingSessionBufferingEnd()250 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionBufferingEnd()
251 {
252 if (ipSessionDurationTimer)
253 {
254 ComputeCurrentSessionDurationMonitoringInterval();
255 ipSessionDurationTimer->Start();
256 }
257 }
258
SetBroadcastSession()259 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetBroadcastSession()
260 {
261 iBroadcastSession = true;
262 }
263
ResetEstimatedServerClock()264 OSCL_EXPORT_REF void PVMFJitterBufferMisc::ResetEstimatedServerClock()
265 {
266 if (ipEstimatedServerClock)
267 {
268 uint32 start = 0;
269 ipEstimatedServerClock->Stop();
270 bool overflowFlag = false;
271 ipEstimatedServerClock->SetStartTime32(start, PVMF_MEDIA_CLOCK_MSEC, overflowFlag);
272 }
273 }
274
PrepareForRepositioning(bool oUseExpectedClientClockVal,uint32 aExpectedClientClockVal)275 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::PrepareForRepositioning(bool oUseExpectedClientClockVal, uint32 aExpectedClientClockVal)
276 {
277 bool overflowFlag = false;
278
279 //A session will have three things
280 //Media channel : Valid for any type of streaming
281 //Feedback Channel : Valid for RTSP based streaming
282 //Session Info : Valid for any type of streaming
283
284 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
285 for (it = irPortParamsQueue.begin();
286 it != irPortParamsQueue.end();
287 it++)
288 {
289 PVMFJitterBufferPortParams* pPortParam = *it;
290 if (pPortParam->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
291 {
292 pPortParam->ipJitterBuffer->PrepareForRepositioning();
293 }
294 }
295
296 PVMFTimestamp ts = 0;
297 if (oUseExpectedClientClockVal)
298 {
299 ts = aExpectedClientClockVal;
300 }
301 else
302 {
303 //reset player clock
304 ts = GetActualMediaDataTSAfterSeek();
305 }
306
307 irClientPlaybackClock.Stop();
308 irClientPlaybackClock.SetStartTime32(ts,
309 PVMF_MEDIA_CLOCK_MSEC, overflowFlag);
310
311 LOGCLIENTANDESTIMATEDSERVCLK_DATAPATH;
312 LOGCLIENTANDESTIMATEDSERVCLK_DATAPATH_OUT;
313 LOGCLIENTANDESTIMATEDSERVCLK_REBUFF;
314
315 if (ipRTCPProtoImplementator)
316 ipRTCPProtoImplementator->Prepare(true);
317 iStreamingSessionExpired = false;
318
319 return true;
320 }
321
PurgeElementsWithNPTLessThan(NptTimeFormat & aNPTTime)322 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::PurgeElementsWithNPTLessThan(NptTimeFormat &aNPTTime)
323 {
324 if (aNPTTime.npt_format != NptTimeFormat::NPT_SEC)
325 {
326 return false;
327 }
328
329 uint32 i;
330 for (i = 0; i < irPortParamsQueue.size(); i++)
331 {
332 PVMFJitterBufferPortParams* portParams = irPortParamsQueue[i];
333 portParams->irPort.ClearMsgQueues();
334 }
335
336 for (i = 0; i < irPortParamsQueue.size(); i++)
337 {
338 PVMFJitterBufferPortParams* portParams = irPortParamsQueue[i];
339 if (portParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
340 {
341 if (portParams->ipJitterBuffer != NULL)
342 {
343 //portParams.iJitterBuffer->FlushJitterBuffer();
344 PVMFTimestamp baseTS = 1000 * aNPTTime.npt_sec.sec + aNPTTime.npt_sec.milli_sec;
345
346 portParams->iMediaClockConverter.set_clock_other_timescale(baseTS, 1000);
347 baseTS = portParams->iMediaClockConverter.get_current_timestamp();
348 portParams->ipJitterBuffer->PurgeElementsWithTimestampLessThan(baseTS);
349 }
350 }
351 }
352
353 // Update client clock here to avoid premature buffer fullness
354 PVMFTimestamp ts = 1000 * aNPTTime.npt_sec.sec + aNPTTime.npt_sec.milli_sec;
355 bool overflowFlag = false;
356 irClientPlaybackClock.Stop();
357 irClientPlaybackClock.SetStartTime32(ts, PVMF_MEDIA_CLOCK_MSEC, overflowFlag);
358 return true;
359 }
360
IsSessionExpired()361 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::IsSessionExpired()
362 {
363 return iStreamingSessionExpired;
364 }
365
Prepare()366 OSCL_EXPORT_REF void PVMFJitterBufferMisc::Prepare()
367 {
368 if (ipNonDecreasingClock)
369 {
370 ipNonDecreasingClock->Start();
371 }
372
373 if (ipWallClock)
374 {
375 //Starts if not already running, check for state
376 ipWallClock->Start();
377 }
378
379 if (UseSessionDurationTimerForEOS())
380 {
381 ipSessionDurationTimer = OSCL_NEW(PvmfJBSessionDurationTimer, (this));
382 if (ipSessionDurationTimer && ipEstimatedServerClock)
383 {
384 ipSessionDurationTimer->SetEstimatedServerClock(ipEstimatedServerClock);
385 }
386 }
387 if (RTCPProtocolImplementorRequired())
388 {
389 ipRTCPProtoImplementator = PVRTCPProtoImplementor::New(irClientPlaybackClock, *ipWallClock, this, iBroadcastSession);
390
391 //Set the rate adaptaton parmas if not already set
392 PVMFPortInterface* feedbackPort = NULL;
393 PVMFJitterBuffer* jitterBuffer = NULL;
394 Oscl_Vector<RateAdapatationInfo, OsclMemAllocator>::iterator iter;
395 for (iter = iRateAdaptationInfos.begin(); iter < iRateAdaptationInfos.end(); iter++)
396 {
397 RateAdapatationInfo rateAdaptationInfo = *iter;
398 feedbackPort = NULL;
399 jitterBuffer = NULL;
400 if (LookupRTCPChannelParams(rateAdaptationInfo.iPort, feedbackPort, jitterBuffer))
401 {
402 PVRTCPChannelController* rtcpChannelController = ipRTCPProtoImplementator->GetRTCPChannelController(feedbackPort);
403 if (rtcpChannelController)
404 {
405 rtcpChannelController->SetRateAdaptation(rateAdaptationInfo.iRateAdapatationInfo.iRateAdaptation, rateAdaptationInfo.iRateAdapatationInfo.iRateAdaptationFeedBackFrequency, rateAdaptationInfo.iRateAdapatationInfo.iRateAdaptationFreeBufferSpaceInBytes);
406
407 }
408 else
409 {
410 PVMFJitterBufferPort* rtpDataPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, rateAdaptationInfo.iPort);
411 jitterBuffer = rtpDataPort->GetPortParams()->ipJitterBuffer;
412 PVMFJitterBufferPortParams* rtpPortParams = rtpDataPort->GetPortParams();
413 PVMFJitterBufferPortParams* feedbackPortParams = NULL;
414 LocateFeedBackPort(rtpPortParams, feedbackPortParams);
415 if (feedbackPortParams)
416 {
417 feedbackPort = &feedbackPortParams->irPort;
418 }
419 rtcpChannelController = PVRTCPChannelController::New(ipRTCPProtoImplementator, *jitterBuffer, feedbackPort, irClientPlaybackClock, *ipWallClock);
420 rtcpChannelController->SetRateAdaptation(rateAdaptationInfo.iRateAdapatationInfo.iRateAdaptation, rateAdaptationInfo.iRateAdapatationInfo.iRateAdaptationFeedBackFrequency, rateAdaptationInfo.iRateAdapatationInfo.iRateAdaptationFreeBufferSpaceInBytes);
421 ipRTCPProtoImplementator->AddPVRTCPChannelController(rtcpChannelController);
422 }
423 }
424 }
425
426 Oscl_Vector<RTCPParams, OsclMemAllocator>::iterator rtcpParamIter;
427 for (rtcpParamIter = iRTCPParamsVect.begin(); rtcpParamIter < iRTCPParamsVect.end(); rtcpParamIter++)
428 {
429 RTCPParams rtcpParams = *rtcpParamIter;
430 ipRTCPProtoImplementator->SetPortRTCPParams(rtcpParams.iFeedbackPort, rtcpParams.iNumSenders, rtcpParams.iRR, rtcpParams.iRS);
431 }
432
433 {
434 //Provide media clcok converter
435 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
436 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
437 {
438 PVMFJitterBufferPortParams* pPortParams = *iter;
439 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
440 {
441
442 SetMediaClockConverter(&pPortParams->irPort, &pPortParams->iMediaClockConverter);
443 }
444 }
445 }
446 }
447
448 iRateAdaptationInfos.clear();
449 iRTCPParamsVect.clear();
450 }
451
Reset()452 OSCL_EXPORT_REF void PVMFJitterBufferMisc::Reset()
453 {
454 if (ipEventNotifier)
455 {
456 ipEventNotifier->CancelAllPendingCallbacks();
457 }
458 if (ipSessionDurationTimer)
459 {
460 ipSessionDurationTimer->Stop();
461 }
462 if (ipRTCPProtoImplementator)
463 {
464 ipRTCPProtoImplementator->Reset();
465 }
466 if (ipFireWallPacketExchangerImpl)
467 {
468 ipFireWallPacketExchangerImpl->CancelFirewallPacketExchange();
469 }
470 if (ipEstimatedServerClock)
471 {
472 ipEstimatedServerClock->Stop();
473 }
474 if (ipWallClock)
475 {
476 ipWallClock->Stop();
477 }
478 if (ipNonDecreasingClock)
479 {
480 ipNonDecreasingClock->Stop();
481 }
482
483 iSessionDuration = 0;
484 iStreamingSessionExpired = true;
485 iPlayDurationAvailable = false;
486 iBroadcastSession = false;
487 iFireWallPacketsExchangeEnabled = true;
488 }
489
PrepareMediaReceivingChannel()490 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferMisc::PrepareMediaReceivingChannel()
491 {
492 if (ipFireWallPacketExchangerImpl && iFireWallPacketsExchangeEnabled)
493 {
494 ipFireWallPacketExchangerImpl->InitiateFirewallPacketExchange();
495 return PVMFPending;
496 }
497 else
498 {
499 if (!iFireWallPacketsExchangeEnabled)
500 {
501 ipObserver->MediaReceivingChannelPrepared(true);
502 return PVMFSuccess;
503 }
504 return PVMFPending; //Wait for the SetServerInfo call
505 }
506 }
507
CancelMediaReceivingChannelPreparation()508 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferMisc::CancelMediaReceivingChannelPreparation()
509 {
510 if (ipFireWallPacketExchangerImpl)
511 ipFireWallPacketExchangerImpl->CancelFirewallPacketExchange();
512 return PVMFSuccess;
513 }
514
FirewallPacketExchangerRequired() const515 bool PVMFJitterBufferMisc::FirewallPacketExchangerRequired() const
516 {
517 if (iFireWallPacketsExchangeEnabled)
518 {
519 char mimeRequiredForFirewallPacketExchange[] = "rtp";
520 char mediaChannelMimeType[255] = {'0'};
521 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
522 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end(); iter++)
523 {
524 PVMFJitterBufferPortParams* pPortParams = *iter;
525 if (pPortParams && (pPortParams->ipJitterBuffer))
526 {
527 oscl_memset(mediaChannelMimeType, 0, sizeof(mediaChannelMimeType));
528 const char* tmpMediaChannelMimeType = pPortParams->ipJitterBuffer->GetMimeType();
529 const int32 mediaChannelMimeLen = oscl_strlen(tmpMediaChannelMimeType);
530 if (tmpMediaChannelMimeType)
531 {
532 for (int ii = 0; ii < mediaChannelMimeLen; ii++)
533 {
534 mediaChannelMimeType[ii] = oscl_tolower(tmpMediaChannelMimeType[ii]);
535 }
536 mediaChannelMimeType[mediaChannelMimeLen] = '\0';
537 }
538
539 if (oscl_strstr(mediaChannelMimeType, mimeRequiredForFirewallPacketExchange))
540 {
541 return true;
542 }
543 }
544 }
545 }
546 return false;
547 }
548
RTCPProtocolImplementorRequired() const549 bool PVMFJitterBufferMisc::RTCPProtocolImplementorRequired() const
550 {
551 char mimeRequiredForRTCPSupport[] = "rtp";
552 char mediaChannelMimeType[255] = {'0'};
553 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
554 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end(); iter++)
555 {
556 PVMFJitterBufferPortParams* pPortParams = *iter;
557 if (pPortParams && (pPortParams->ipJitterBuffer))
558 {
559 oscl_memset(mediaChannelMimeType, 0, sizeof(mediaChannelMimeType));
560 const char* tmpMediaChannelMimeType = pPortParams->ipJitterBuffer->GetMimeType();
561 const int32 mediaChannelMimeLen = oscl_strlen(tmpMediaChannelMimeType);
562 if (tmpMediaChannelMimeType)
563 {
564 for (int ii = 0; ii < mediaChannelMimeLen; ii++)
565 {
566 mediaChannelMimeType[ii] = oscl_tolower(tmpMediaChannelMimeType[ii]);
567 }
568 mediaChannelMimeType[mediaChannelMimeLen] = '\0';
569 }
570
571 if (oscl_strstr(mediaChannelMimeType, mimeRequiredForRTCPSupport))
572 {
573 return true;
574 }
575 }
576 }
577 return false;//based on mime type
578 }
579
ProcessFeedbackMessage(PVMFJitterBufferPortParams & aParam,PVMFSharedMediaMsgPtr aMsg)580 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferMisc::ProcessFeedbackMessage(PVMFJitterBufferPortParams& aParam, PVMFSharedMediaMsgPtr aMsg)
581 {
582 PVMFStatus status = PVMFSuccess;
583 if (ipRTCPProtoImplementator)
584 {
585 status = ipRTCPProtoImplementator->ProcessRTCPReport(&aParam.irPort, aMsg);
586 }
587 else
588 {
589 status = PVMFFailure;
590 }
591 return status;
592 }
593
SetRateAdaptationInfo(PVMFPortInterface * aPort,bool aRateAdaptation,uint32 aRateAdaptationFeedBackFrequency,uint32 aRateAdaptationFreeBufferSpaceInBytes)594 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetRateAdaptationInfo(PVMFPortInterface* aPort, bool aRateAdaptation, uint32 aRateAdaptationFeedBackFrequency, uint32 aRateAdaptationFreeBufferSpaceInBytes)
595 {
596 //Persist it: We'll update it when RTCP controller will be prepared
597 RateAdapatationInfo rateAdadpatatinInfo;
598 rateAdadpatatinInfo.iPort = aPort;
599 rateAdadpatatinInfo.iRateAdapatationInfo.iRateAdaptation = aRateAdaptation;
600 rateAdadpatatinInfo.iRateAdapatationInfo.iRateAdaptationFeedBackFrequency = aRateAdaptationFeedBackFrequency;
601 rateAdadpatatinInfo.iRateAdapatationInfo.iRateAdaptationFreeBufferSpaceInBytes = aRateAdaptationFreeBufferSpaceInBytes;
602 iRateAdaptationInfos.push_back(rateAdadpatatinInfo);
603 }
604
SetRTCPIntervalInMicroSecs(uint32 aRTCPInterval)605 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetRTCPIntervalInMicroSecs(uint32 aRTCPInterval)
606 {
607 if (ipRTCPProtoImplementator)
608 ipRTCPProtoImplementator->SetRTCPIntervalInMicroSecs(aRTCPInterval);
609 }
610
SetPortRTCPParams(PVMFPortInterface * aPort,int aNumSenders,uint32 aRR,uint32 aRS)611 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::SetPortRTCPParams(PVMFPortInterface* aPort, int aNumSenders, uint32 aRR, uint32 aRS)
612 {
613 bool retval = false;
614 if (ipRTCPProtoImplementator)
615 retval = ipRTCPProtoImplementator->SetPortRTCPParams(aPort, aNumSenders, aRR, aRS);
616 //retval eq to false implies rtcp controller doesnt exist as fo now for the port "aPort"
617 if (!retval)
618 {
619 RTCPParams rtcpParams;
620 rtcpParams.iFeedbackPort = aPort;
621 rtcpParams.iNumSenders = aNumSenders;
622 rtcpParams.iRR = aRR;
623 rtcpParams.iRS = aRS;
624 iRTCPParamsVect.push_back(rtcpParams);
625 retval = true;
626 }
627 return retval;
628 }
629
ResetSession()630 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::ResetSession()
631 {
632 iStreamingSessionExpired = false;
633 if (ipSessionDurationTimer)
634 {
635 ipSessionDurationTimer->Cancel();
636 ipSessionDurationTimer->Stop();
637 }
638 return true;
639 }
640
SetSessionDurationExpired()641 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::SetSessionDurationExpired()
642 {
643 iStreamingSessionExpired = true;
644 if (ipSessionDurationTimer)
645 {
646 ipSessionDurationTimer->Cancel();
647 ipSessionDurationTimer->Stop();
648 }
649
650 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
651 for (it = irPortParamsQueue.begin(); it != irPortParamsQueue.end(); it++)
652 {
653 PVMFJitterBufferPortParams* pPortParams = *it;
654
655 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
656 {
657 pPortParams->ipJitterBuffer->SetEOS(true);
658 }
659 }
660
661
662 uint32 timebase32 = 0;
663 uint32 clientClock32 = 0;
664 bool overflowFlag = false;
665 irClientPlaybackClock.GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
666 timebase32 = 0;
667 uint32 estServClock32 = 0;
668 ipEstimatedServerClock->GetCurrentTime32(estServClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
669
670 PVMF_JB_LOGDATATRAFFIC_OUT((0, "PVMFJitterBufferMisc::SetSessionDurationExpired- Estimated Server Clock [%d] Client Clock[%d]", estServClock32, clientClock32));
671 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferMisc::SetSessionDurationExpired- Estimated Server Clock [%d] Client Clock[%d]", estServClock32, clientClock32));
672
673 return true;
674 }
675
MediaReceivingChannelPreparationRequired(bool aRequired)676 OSCL_EXPORT_REF void PVMFJitterBufferMisc::MediaReceivingChannelPreparationRequired(bool aRequired)
677 {
678 iFireWallPacketsExchangeEnabled = aRequired;
679 }
680
GetEstimatedServerClock()681 OSCL_EXPORT_REF PVMFMediaClock& PVMFJitterBufferMisc::GetEstimatedServerClock()
682 {
683 return *ipEstimatedServerClock;
684 }
685
GetEventNotifier()686 OSCL_EXPORT_REF PVMFJBEventNotifier* PVMFJitterBufferMisc::GetEventNotifier()
687 {
688 return ipEventNotifier;
689 }
690
SetPlayRange(int32 aStartTimeInMS,int32 aStopTimeInMS,bool aPlayAfterASeek,bool aStopTimeAvailable)691 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::SetPlayRange(int32 aStartTimeInMS, int32 aStopTimeInMS, bool aPlayAfterASeek, bool aStopTimeAvailable)
692 {
693 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
694 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
695 {
696 PVMFJitterBufferPortParams* pPortParam = *iter;
697 if (pPortParam && (PVMF_JITTER_BUFFER_PORT_TYPE_INPUT == pPortParam->iTag))
698 {
699 PVMFJitterBuffer* jitterBuffer = pPortParam->ipJitterBuffer;
700 if (jitterBuffer)
701 {
702 jitterBuffer->SetPlayRange(aStartTimeInMS, aPlayAfterASeek, aStopTimeAvailable, aStopTimeInMS);
703 }
704 }
705 }
706
707 //Configure the RTCP timer stuff
708 if (ipRTCPProtoImplementator)
709 {
710 ipRTCPProtoImplementator->Prepare(aPlayAfterASeek);
711 ipRTCPProtoImplementator->StartRTCPMessageExchange();
712 }
713
714 iPlayStartTimeInMS = aStartTimeInMS;
715 iPlayStopTimeInMS = aStopTimeInMS;
716 iPlayStopTimeAvailable = aStopTimeAvailable;
717
718 if (iPlayStopTimeAvailable == true)
719 {
720 /* Start Session Duration Timer only if stop duration is set */
721 if ((ipSessionDurationTimer) && (!iStreamingSessionExpired || (aPlayAfterASeek)))
722 {
723 ipSessionDurationTimer->Stop();
724 iStreamingSessionExpired = false;
725 ipSessionDurationTimer->setSessionDurationInMS(((iPlayStopTimeInMS - iPlayStartTimeInMS) + PVMF_EOS_TIMER_GAURD_BAND_IN_MS));
726 ComputeCurrentSessionDurationMonitoringInterval();
727 ipSessionDurationTimer->Start();
728 }
729 }
730
731 if (aPlayAfterASeek)
732 {
733 //Will eventually update the estimated server clock
734 //This call to "GetActualMediaDataTSAfterSeek" will normalize the ts's across the jitter buffers
735 //associated with the streaming session
736 GetActualMediaDataTSAfterSeek();
737 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
738 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
739 {
740 PVMFJitterBufferPortParams* pPortParams = *iter;
741 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
742 {
743 if (pPortParams->ipJitterBuffer != NULL)
744 {
745 pPortParams->ipJitterBuffer->AdjustRTPTimeStamp();
746 }
747 }
748 }
749 }
750 return true;
751 }
752
SetPortSSRC(PVMFPortInterface * aPort,uint32 aSSRC)753 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetPortSSRC(PVMFPortInterface* aPort, uint32 aSSRC)
754 {
755 bool isUpdateRequest = false;
756
757 for (uint32 ii = 0; ii < iRTPExchangeInfosForFirewallExchange.size(); ii++)
758 {
759 if (aPort == iRTPExchangeInfosForFirewallExchange[ii].ipRTPDataJitterBufferPort)
760 {
761 isUpdateRequest = true;
762 iRTPExchangeInfosForFirewallExchange[ii].iSSRC = aSSRC;
763 ipFireWallPacketExchangerImpl->SetRTPSessionInfoForFirewallExchange(iRTPExchangeInfosForFirewallExchange[ii]);
764 break;
765 }
766 }
767
768 if (!isUpdateRequest)
769 {
770 //Update with the JB
771 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::const_iterator iter;
772 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; ++iter)
773 {
774 if ( iter && (*iter) && (&((*iter)->irPort) == aPort))
775 {
776 if ((*iter)->ipJitterBuffer)
777 {
778 (*iter)->ipJitterBuffer->setSSRC(aSSRC);
779 }
780 break;
781 }
782 }
783 //update port's ssrc with the Firewall controller
784 RTPSessionInfoForFirewallExchange rtpSessioninfo(aPort, aSSRC);
785 iRTPExchangeInfosForFirewallExchange.push_back(rtpSessioninfo);
786 }
787 }
788
GetEstimatedServerClockValue()789 OSCL_EXPORT_REF uint32 PVMFJitterBufferMisc::GetEstimatedServerClockValue()
790 {
791 uint32 serverClock32 = 0;
792 bool overflowFlag = false;
793 ipEstimatedServerClock->GetCurrentTime32(serverClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
794 return serverClock32;
795 }
796
PlayStopTimeAvailable() const797 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::PlayStopTimeAvailable() const
798 {
799 return iPlayStopTimeAvailable;
800 }
801
SetServerInfo(PVMFJitterBufferFireWallPacketInfo & aServerInfo)802 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetServerInfo(PVMFJitterBufferFireWallPacketInfo& aServerInfo)
803 {
804 if (iFireWallPacketsExchangeEnabled)
805 {
806 if (!ipFireWallPacketExchangerImpl)
807 {
808 if (iRTPExchangeInfosForFirewallExchange.size() == 0)//We haven't got the exchange info for the firewall pkts yet, lets assume ssrc to be zero for all the feedback ports
809 {
810 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
811 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end(); ++iter)
812 {
813 PVMFJitterBufferPortParams* portParams = *iter;
814 if (portParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
815 {
816 RTPSessionInfoForFirewallExchange rtpSessioninfo(&portParams->irPort, 0);
817 iRTPExchangeInfosForFirewallExchange.push_back(rtpSessioninfo);
818 }
819 }
820 }
821
822 //create it and start firewall packet exchange
823 ipFireWallPacketExchangerImpl = PVFirewallPacketExchangeImpl::New(aServerInfo, *ipEventNotifier, ipObserver);
824 Oscl_Vector<RTPSessionInfoForFirewallExchange, OsclMemAllocator>::iterator iter;
825
826 for (iter = iRTPExchangeInfosForFirewallExchange.begin(); iter != iRTPExchangeInfosForFirewallExchange.end(); iter++)
827 {
828 ipFireWallPacketExchangerImpl->SetRTPSessionInfoForFirewallExchange(*iter);
829 }
830
831 ipFireWallPacketExchangerImpl->InitiateFirewallPacketExchange();
832 }
833 else
834 {
835 OSCL_ASSERT(false);
836 }
837 }
838 }
839
GetMaxMediaDataTS()840 OSCL_EXPORT_REF PVMFTimestamp PVMFJitterBufferMisc::GetMaxMediaDataTS()
841 {
842 PVMFTimestamp mediaTS = 0;
843 uint32 in_wrap_count = 0;
844 uint32 i;
845
846 uint32 numOfJitterBuffers = 0;
847 for (i = 0; i < irPortParamsQueue.size(); i++)
848 {
849 PVMFJitterBufferPortParams* pPortParams = irPortParamsQueue[i];
850
851 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
852 {
853 if (pPortParams->ipJitterBuffer != NULL)
854 {
855 PVMFTimestamp ts =
856 pPortParams->ipJitterBuffer->peekNextElementTimeStamp();
857 ++numOfJitterBuffers;
858 /*
859 * Convert Time stamp to milliseconds
860 */
861 pPortParams->iMediaClockConverter.set_clock(ts, in_wrap_count);
862 PVMFTimestamp converted_ts =
863 pPortParams->iMediaClockConverter.get_converted_ts(1000);
864 if (converted_ts > mediaTS)
865 {
866 mediaTS = converted_ts;
867 }
868 }
869 }
870 }
871
872 if (numOfJitterBuffers > 1) //Need to normalize ts across jb's with the session (E.g. RTSP based streaming).
873 {
874 for (i = 0; i < irPortParamsQueue.size(); i++)
875 {
876 PVMFJitterBufferPortParams* pPortParams = irPortParamsQueue[i];
877
878 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
879 {
880 if (pPortParams->ipJitterBuffer != NULL)
881 {
882 pPortParams->ipJitterBuffer->SetAdjustedTSInMS(mediaTS);
883 }
884 }
885 }
886 }
887
888 return mediaTS;
889 }
890
891 /* computes the max next ts of all tracks */
GetActualMediaDataTSAfterSeek()892 OSCL_EXPORT_REF PVMFTimestamp PVMFJitterBufferMisc::GetActualMediaDataTSAfterSeek()
893 {
894 PVMFTimestamp mediaTS = 0;
895 uint32 in_wrap_count = 0;
896 uint32 i;
897
898 uint32 numOfJitterBuffers = 0;
899 for (i = 0; i < irPortParamsQueue.size(); i++)
900 {
901 PVMFJitterBufferPortParams* pPortParams = irPortParamsQueue[i];
902
903 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
904 {
905 if (pPortParams->ipJitterBuffer != NULL)
906 {
907 PVMFTimestamp ts =
908 pPortParams->ipJitterBuffer->peekNextElementTimeStamp();
909 ++numOfJitterBuffers;
910 /*
911 * Convert Time stamp to milliseconds
912 */
913 pPortParams->iMediaClockConverter.set_clock(ts, in_wrap_count);
914 PVMFTimestamp converted_ts =
915 pPortParams->iMediaClockConverter.get_converted_ts(1000);
916 if (converted_ts > mediaTS)
917 {
918 mediaTS = converted_ts;
919 }
920 }
921 }
922 }
923
924 if (numOfJitterBuffers > 1) //Need to normalize ts across jb's with the session (E.g. RTSP based streaming).
925 {
926 for (i = 0; i < irPortParamsQueue.size(); i++)
927 {
928 PVMFJitterBufferPortParams* pPortParams = irPortParamsQueue[i];
929
930 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
931 {
932 if (pPortParams->ipJitterBuffer != NULL)
933 {
934 pPortParams->ipJitterBuffer->SetAdjustedTSInMS(mediaTS);
935 }
936 }
937 }
938 }
939
940 return mediaTS;
941 }
942
SetMediaClockConverter(PVMFPortInterface * apPort,MediaClockConverter * apMediaClockConverter)943 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetMediaClockConverter(PVMFPortInterface* apPort, MediaClockConverter* apMediaClockConverter)
944 {
945 PVMFPortInterface* feedbackPort = NULL;
946 PVMFJitterBuffer* jitterBuffer = NULL;
947 if (LookupRTCPChannelParams(apPort, feedbackPort, jitterBuffer))
948 {
949 PVRTCPChannelController* rtcpChannelController = ipRTCPProtoImplementator->GetRTCPChannelController(feedbackPort);
950 if (rtcpChannelController)
951 {
952 rtcpChannelController->SetMediaClockConverter(apMediaClockConverter);
953 }
954 }
955 }
956
ProcessFirstPacketAfterSeek()957 OSCL_EXPORT_REF void PVMFJitterBufferMisc::ProcessFirstPacketAfterSeek()
958 {
959 //This call to "GetActualMediaDataTSAfterSeek" will normalize the ts's across the jitter buffers
960 //associated with the streaming session
961 GetActualMediaDataTSAfterSeek();
962 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
963 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end() ; iter++)
964 {
965 PVMFJitterBufferPortParams* pPortParams = *iter;
966 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
967 {
968 if (pPortParams->ipJitterBuffer != NULL)
969 {
970 pPortParams->ipJitterBuffer->AdjustRTPTimeStamp();
971 }
972 }
973 }
974 }
975
RTCPPacketReceived(RTCPPacketType aPacketType,PVRTCPChannelController * aController)976 PVMFStatus PVMFJitterBufferMisc::RTCPPacketReceived(RTCPPacketType aPacketType, PVRTCPChannelController* aController)
977 {
978 PVMF_JB_LOG_RTCPDATATRAFFIC_IN_E((0, "PVMFJitterBufferMisc::RTCPPacketReceived -- iPlayStopTimeAvailable[%d]", iPlayStopTimeAvailable));
979 if (BYE_RTCP_PACKET == aPacketType && aController)
980 {
981 //for live streams, treat RTCP BYE as EOS
982 if (iPlayStopTimeAvailable == false)
983 {
984 PVMF_JB_LOGDATATRAFFIC_IN((0, "USING RTCP_BYE TO TRIGGER EOS: Mime=%s", aController->GetJitterBuffer().GetMimeType()));
985 PVMF_JB_LOGDATATRAFFIC_OUT((0, "USING RTCP_BYE TO TRIGGER EOS: Mime=%s", aController->GetJitterBuffer().GetMimeType()));
986 PVMF_JB_LOG_RTCPDATATRAFFIC_IN((0, "USING RTCP_BYE TO TRIGGER EOS: Mime=%s", aController->GetJitterBuffer().GetMimeType()));
987 SetSessionDurationExpired();
988 ipEstimatedServerClock->Pause();
989 ipWallClock->Pause();
990 }
991
992 if (ipRTCPProtoImplementator->RTCPByeReceivedOnAllControllers())
993 {
994 SetSessionDurationExpired();
995 ipEstimatedServerClock->Pause();
996 ipWallClock->Pause();
997 }
998
999 PVUuid eventuuid = PVMFJitterBufferNodeEventTypeUUID;
1000 int32 infocode = PVMFJitterBufferNodeRTCPBYERecvd;
1001
1002 PVMFBasicErrorInfoMessage* eventmsg;
1003 eventmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (infocode, eventuuid, NULL));
1004 PVMFErrorInfoMessageInterface* interimPtr =
1005 OSCL_STATIC_CAST(PVMFErrorInfoMessageInterface*, eventmsg);
1006 PVMFAsyncEvent asyncevent(PVMFInfoEvent,
1007 PVMFInfoRemoteSourceNotification,
1008 NULL,
1009 OSCL_STATIC_CAST(PVInterface*, interimPtr),
1010 (OsclAny*)(aController->GetJitterBuffer().GetMimeType()),
1011 NULL,
1012 0);
1013 ipObserver->ProcessRTCPControllerEvent(asyncevent);
1014 eventmsg->removeRef();
1015 }
1016 return PVMFSuccess;
1017 }
1018
RTCPReportReadyToSend(PVMFPortInterface * & aPort,PVMFSharedMediaMsgPtr & aMessage)1019 PVMFStatus PVMFJitterBufferMisc::RTCPReportReadyToSend(PVMFPortInterface*& aPort, PVMFSharedMediaMsgPtr& aMessage)
1020 {
1021 ipObserver->MessageReadyToSend(aPort, aMessage);
1022 return PVMFSuccess;
1023 }
1024
ProcessInfoEvent(PVMFAsyncEvent & aEvent)1025 PVMFStatus PVMFJitterBufferMisc::ProcessInfoEvent(PVMFAsyncEvent& aEvent)
1026 {
1027 ipObserver->ProcessRTCPControllerEvent(aEvent);
1028 return PVMFSuccess;
1029 }
1030
PVMFJBSessionDurationTimerEvent()1031 void PVMFJitterBufferMisc::PVMFJBSessionDurationTimerEvent()
1032 {
1033 PVMF_JB_LOGCLOCK((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - Session Duration Timer Expired"));
1034 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - Session Duration Timer Expired"));
1035 /* Check if the estimated server clock is past the expected value */
1036 uint32 expectedEstServClockVal =
1037 ipSessionDurationTimer->GetExpectedEstimatedServClockValAtSessionEnd();
1038 uint32 timebase32 = 0;
1039 uint32 estServClock = 0;
1040 bool overflowFlag = false;
1041
1042
1043 ipEstimatedServerClock->GetCurrentTime32(estServClock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
1044 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - CurrEstServClock = %2d", estServClock));
1045 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - ExpectedEstServClock = %2d", expectedEstServClockVal));
1046 if (estServClock >= expectedEstServClockVal)
1047 {
1048 PVMF_JB_LOG_EVENTS_CLOCK((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent estServClock[%d] expectedEstServClockVal[%d]", estServClock, expectedEstServClockVal));
1049 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - Session Duration Has Elapsed"));
1050 iStreamingSessionExpired = true;
1051 ipObserver->SessionSessionExpired();
1052 /* Cancel clock update notifications */
1053 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
1054 for (it = irPortParamsQueue.begin(); it != irPortParamsQueue.end(); it++)
1055 {
1056 PVMFJitterBufferPortParams* pPortParams = *it;
1057
1058 if (pPortParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
1059 {
1060 pPortParams->ipJitterBuffer->SetEOS(true);
1061 }
1062 }
1063 /* Pause Estimated server clock & RTCP Clock */
1064 ipEstimatedServerClock->Pause();
1065 ipWallClock->Pause();
1066 }
1067 else
1068 {
1069 /*
1070 * Since we monitor the session duration in intervals, it is possible that this call back
1071 * happens when one such interval expires
1072 */
1073 uint64 elapsedTime = ipSessionDurationTimer->GetMonitoringIntervalElapsed();
1074 uint32 elapsedTime32 = Oscl_Int64_Utils::get_uint64_lower32(elapsedTime);
1075 ipSessionDurationTimer->UpdateElapsedSessionDuration(elapsedTime32);
1076 uint32 totalSessionDuration = ipSessionDurationTimer->getSessionDurationInMS();
1077 uint32 elapsedSessionDurationInMS = ipSessionDurationTimer->GetElapsedSessionDurationInMS();
1078 if (elapsedSessionDurationInMS < totalSessionDuration)
1079 {
1080 uint32 interval = (totalSessionDuration - elapsedSessionDurationInMS);
1081 if (interval > PVMF_JITTER_BUFFER_NODE_SESSION_DURATION_MONITORING_INTERVAL_MAX_IN_MS)
1082 {
1083 interval = PVMF_JITTER_BUFFER_NODE_SESSION_DURATION_MONITORING_INTERVAL_MAX_IN_MS;
1084 }
1085 ipSessionDurationTimer->setCurrentMonitoringIntervalInMS(interval);
1086 ipSessionDurationTimer->ResetEstimatedServClockValAtLastCancel();
1087 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - TotalDuration=%d, ElapsedDuration=%d, CurrMonitoringInterval=%d", totalSessionDuration, elapsedSessionDurationInMS, interval));
1088 }
1089 else
1090 {
1091 /*
1092 * 1) Register for est serv clock update notifications on all jitter buffers
1093 * 2) Reschedule the session duration timer
1094 */
1095 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - Past Session End Time - Starting to monitor Estimated Server Clock expectedEstServClockVal%d estServClock %d", expectedEstServClockVal, estServClock));
1096
1097 uint64 diff = (expectedEstServClockVal - estServClock);
1098 uint32 diff32 = Oscl_Int64_Utils::get_uint64_lower32(diff);
1099
1100 PVMFJBEventNotificationRequestInfo requestInfo(CLOCK_NOTIFICATION_INTF_TYPE_ESTIMATEDSERVER, this, NULL);
1101
1102 if (iEstimatedServerClockUpdateCallbackPending)
1103 {
1104 ipEventNotifier->CancelCallBack(requestInfo, iEstimatedServerClockUpdateCallbackId);
1105 iEstimatedServerClockUpdateCallbackPending = false;
1106 }
1107
1108 ipEventNotifier->RequestAbsoluteTimeCallBack(requestInfo, expectedEstServClockVal, iEstimatedServerClockUpdateCallbackId);
1109 iEstimatedServerClockUpdateCallbackPending = true;
1110
1111 /*
1112 * This is intentional. We do not expect the session duration and monitoring
1113 * intervals to exceed the max timer limit of 32 mins
1114 */
1115 ipSessionDurationTimer->setSessionDurationInMS(diff32);
1116 ipSessionDurationTimer->setCurrentMonitoringIntervalInMS(diff32);
1117 ipSessionDurationTimer->ResetEstimatedServClockValAtLastCancel();
1118 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - ExpectedEstServClock=%d EstServClock=%d", Oscl_Int64_Utils::get_uint64_lower32(expectedEstServClockVal), Oscl_Int64_Utils::get_uint64_lower32(estServClock)));
1119 PVMF_JB_LOGCLOCK_SESSION_DURATION((0, "PVMFJitterBufferNode::PVMFJBSessionDurationTimerEvent - TotalDuration=%d, Interval=%d", diff32, diff32));
1120 }
1121 ipSessionDurationTimer->Start();
1122 }
1123 return;
1124 }
1125
ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType,uint32 aCallBkId,const OsclAny * aContext,PVMFStatus aStatus)1126 void PVMFJitterBufferMisc::ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType, uint32 aCallBkId, const OsclAny* aContext, PVMFStatus aStatus)
1127 {
1128 OSCL_UNUSED_ARG(aClockNotificationInterfaceType);
1129 OSCL_UNUSED_ARG(aContext);
1130 if (aCallBkId == iEstimatedServerClockUpdateCallbackId && (PVMFSuccess == aStatus))
1131 {
1132 ipSessionDurationTimer->EstimatedServerClockUpdated();
1133 }
1134 }
1135
UseSessionDurationTimerForEOS()1136 bool PVMFJitterBufferMisc::UseSessionDurationTimerForEOS()
1137 {
1138 char mimeForSessioDurationTmrNecessity[] = "rtp";
1139 char mediaChannelMimeType[255] = {'0'};
1140 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator iter;
1141 for (iter = irPortParamsQueue.begin(); iter != irPortParamsQueue.end(); iter++)
1142 {
1143 PVMFJitterBufferPortParams* pPortParams = *iter;
1144 if (pPortParams && (pPortParams->ipJitterBuffer))
1145 {
1146 oscl_memset(mediaChannelMimeType, 0, sizeof(mediaChannelMimeType));
1147 const char* tmpMediaChannelMimeType = pPortParams->ipJitterBuffer->GetMimeType();
1148 const int32 mediaChannelMimeLen = oscl_strlen(tmpMediaChannelMimeType);
1149 if (tmpMediaChannelMimeType)
1150 {
1151 for (int ii = 0; ii < mediaChannelMimeLen; ii++)
1152 {
1153 mediaChannelMimeType[ii] = oscl_tolower(tmpMediaChannelMimeType[ii]);
1154 }
1155 mediaChannelMimeType[mediaChannelMimeLen] = '\0';
1156 }
1157
1158 if (oscl_strstr(mediaChannelMimeType, mimeForSessioDurationTmrNecessity))
1159 {
1160 return true;
1161 }
1162 }
1163 }
1164 return false;//based on mime type
1165 }
1166
LogClientAndEstimatedServerClock(PVLogger * aLogger)1167 void PVMFJitterBufferMisc::LogClientAndEstimatedServerClock(PVLogger* aLogger)
1168 {
1169 uint32 timebase32 = 0;
1170 uint32 clientClock32 = 0;
1171 uint32 serverClock32 = 0;
1172 bool overflowFlag = false;
1173 irClientPlaybackClock.GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
1174
1175 if (ipEstimatedServerClock)
1176 ipEstimatedServerClock->GetCurrentTime32(serverClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
1177
1178 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, aLogger, PVLOGMSG_INFO, (0, "Value of Client Clock %d and value of Estimated Sever Clock %d", clientClock32, serverClock32));
1179 }
1180
LookupRTCPChannelParams(PVMFPortInterface * rtpPort,PVMFPortInterface * & rtcpPort,PVMFJitterBuffer * & rtpPktJitterBuffer)1181 bool PVMFJitterBufferMisc::LookupRTCPChannelParams(PVMFPortInterface* rtpPort, PVMFPortInterface*& rtcpPort, PVMFJitterBuffer*& rtpPktJitterBuffer)
1182 {
1183 bool retval = false;
1184 PVMFJitterBufferPort* jbInputPort = OSCL_STATIC_CAST(PVMFJitterBufferPort*, rtpPort);
1185 PVMFJitterBufferPortParams* inputPortParams = jbInputPort->GetPortParams();
1186 PVMFJitterBufferPortParams* feedbackPortParams = NULL;
1187
1188 if (LocateFeedBackPort(inputPortParams, feedbackPortParams))
1189 {
1190 rtcpPort = &feedbackPortParams->irPort;
1191 rtpPktJitterBuffer = inputPortParams->ipJitterBuffer;
1192 retval = true;
1193 }
1194 return retval;
1195 }
1196
LocateFeedBackPort(PVMFJitterBufferPortParams * & aInputPortParamsPtr,PVMFJitterBufferPortParams * & aFeedBackPortParamsPtr)1197 bool PVMFJitterBufferMisc::LocateFeedBackPort(PVMFJitterBufferPortParams*& aInputPortParamsPtr, PVMFJitterBufferPortParams*& aFeedBackPortParamsPtr)
1198 {
1199 uint32 inputPortId = aInputPortParamsPtr->iId;
1200
1201 /* Feedback port id must be inputPortId + 2 */
1202
1203 Oscl_Vector<PVMFJitterBufferPortParams*, OsclMemAllocator>::iterator it;
1204
1205 for (it = irPortParamsQueue.begin(); it != irPortParamsQueue.end(); it++)
1206 {
1207 PVMFJitterBufferPortParams* portParams = *it;
1208 if ((portParams->iTag == PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK) &&
1209 ((int32)portParams->iId == (int32)inputPortId + 2))
1210 {
1211 aFeedBackPortParamsPtr = portParams;
1212 return true;
1213 }
1214 }
1215 return false;
1216 }
1217