Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    244 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionBufferingStart()
    245 {
    246     if (ipSessionDurationTimer)
    247         ipSessionDurationTimer->Cancel();
    248 }
    249 
    250 OSCL_EXPORT_REF void PVMFJitterBufferMisc::StreamingSessionBufferingEnd()
    251 {
    252     if (ipSessionDurationTimer)
    253     {
    254         ComputeCurrentSessionDurationMonitoringInterval();
    255         ipSessionDurationTimer->Start();
    256     }
    257 }
    258 
    259 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetBroadcastSession()
    260 {
    261     iBroadcastSession = true;
    262 }
    263 
    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 
    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 
    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 
    361 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::IsSessionExpired()
    362 {
    363     return iStreamingSessionExpired;
    364 }
    365 
    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 
    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 
    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 
    508 OSCL_EXPORT_REF PVMFStatus PVMFJitterBufferMisc::CancelMediaReceivingChannelPreparation()
    509 {
    510     if (ipFireWallPacketExchangerImpl)
    511         ipFireWallPacketExchangerImpl->CancelFirewallPacketExchange();
    512     return PVMFSuccess;
    513 }
    514 
    515 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 
    549 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 
    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 
    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 
    605 OSCL_EXPORT_REF void PVMFJitterBufferMisc::SetRTCPIntervalInMicroSecs(uint32 aRTCPInterval)
    606 {
    607     if (ipRTCPProtoImplementator)
    608         ipRTCPProtoImplementator->SetRTCPIntervalInMicroSecs(aRTCPInterval);
    609 }
    610 
    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 
    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 
    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 
    676 OSCL_EXPORT_REF void PVMFJitterBufferMisc::MediaReceivingChannelPreparationRequired(bool aRequired)
    677 {
    678     iFireWallPacketsExchangeEnabled = aRequired;
    679 }
    680 
    681 OSCL_EXPORT_REF PVMFMediaClock& PVMFJitterBufferMisc::GetEstimatedServerClock()
    682 {
    683     return *ipEstimatedServerClock;
    684 }
    685 
    686 OSCL_EXPORT_REF PVMFJBEventNotifier* PVMFJitterBufferMisc::GetEventNotifier()
    687 {
    688     return ipEventNotifier;
    689 }
    690 
    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 
    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 
    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 
    797 OSCL_EXPORT_REF bool PVMFJitterBufferMisc::PlayStopTimeAvailable() const
    798 {
    799     return iPlayStopTimeAvailable;
    800 }
    801 
    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 
    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 */
    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 
    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 
    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 
    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 
   1019 PVMFStatus PVMFJitterBufferMisc::RTCPReportReadyToSend(PVMFPortInterface*& aPort, PVMFSharedMediaMsgPtr& aMessage)
   1020 {
   1021     ipObserver->MessageReadyToSend(aPort, aMessage);
   1022     return PVMFSuccess;
   1023 }
   1024 
   1025 PVMFStatus PVMFJitterBufferMisc::ProcessInfoEvent(PVMFAsyncEvent& aEvent)
   1026 {
   1027     ipObserver->ProcessRTCPControllerEvent(aEvent);
   1028     return PVMFSuccess;
   1029 }
   1030 
   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 
   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 
   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 
   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 
   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 
   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