• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #ifndef PVMF_JB_JITTERBUFFERMISC_H_INCLUDED
19 #include "pvmf_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