multimediacommscontroller/mmccsubcontroller/src/mccrtpmediaclock.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    rtp media clock
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include <e32std.h>
       
    22 #include <e32math.h>
       
    23 #include "mccrtpmediaclock.h"
       
    24 #include "mccsubcontrollerlogs.h"
       
    25 
       
    26 // LOCAL CONSTANTS
       
    27 
       
    28 // Helper for calculating next timestamp with sampling rate.
       
    29 const TUint KKiloHzDivider( 1000 );
       
    30 
       
    31 // Idle time limit when no timestamps have been asked from media clock. If
       
    32 // idle time is larger than this, then next timestamp is calculated from
       
    33 // actual time between two timestamp requests.
       
    34 const TInt KIdleTimeStampLimitSecs = 1;
       
    35 
       
    36 // ======== MEMBER FUNCTIONS ========
       
    37 
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // default C++ constructor.
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 CMccRtpMediaClock::CMccRtpMediaClock() : iSamplingFreq( K8Khz ),
       
    44     iHwFrametime( K20ms )
       
    45     {
       
    46     
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // Symbian 2nd phase constructor.
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 void CMccRtpMediaClock::ConstructL()
       
    54     {
       
    55     // Generate random initial rtp timestamp which will be mapped to initial
       
    56     // time. Then take note of the construction time of mediaclock.
       
    57     iPreviousTimestamp.HomeTime();
       
    58     TInt64 seed = iPreviousTimestamp.Int64();
       
    59     iCurRtpTS = Abs( Math::Rand( seed ) );
       
    60     iPreviousTimestamp.UniversalTime();
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // Static constructor.
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CMccRtpMediaClock* CMccRtpMediaClock::NewL()
       
    68     {
       
    69     CMccRtpMediaClock* self = new( ELeave ) CMccRtpMediaClock();
       
    70     CleanupStack::PushL( self );
       
    71     self->ConstructL();
       
    72     CleanupStack::Pop( self );
       
    73     
       
    74     return self;
       
    75     }
       
    76 
       
    77 // ---------------------------------------------------------------------------
       
    78 // Destructor
       
    79 // ---------------------------------------------------------------------------
       
    80 //
       
    81 CMccRtpMediaClock::~CMccRtpMediaClock()
       
    82     {
       
    83     iRegister.Close();
       
    84     }
       
    85 
       
    86 // ---------------------------------------------------------------------------
       
    87 // Each media clock client must register themselves once. If sampling rate or
       
    88 // frametime of the client is changed, client must register again.
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 TUint32 CMccRtpMediaClock::RegisterMediaFormat( TUint aSamplingFreq, 
       
    92                                                 TInt aHwFrametime )
       
    93     {
       
    94     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::RegisterMediaFormat aSamplingFreq: ", aSamplingFreq )
       
    95     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::RegisterMediaFormat aHwFrametime: ", aHwFrametime )
       
    96     
       
    97     // create unique key for client
       
    98     TUint32 key = Math::Random();
       
    99     
       
   100     // create record of registered clients
       
   101     TMccRegInfo reg_info;
       
   102     reg_info.iKey = key;
       
   103     reg_info.iSamplingFreq = aSamplingFreq;
       
   104     reg_info.iHwFrametime = aHwFrametime;
       
   105     iRegister.Append( reg_info );
       
   106     
       
   107     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::RegisterMediaFormat key created: ", key )
       
   108        
       
   109     return key;
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------------------------
       
   113 // Get new timestamp for registered media format
       
   114 // ---------------------------------------------------------------------------
       
   115 //
       
   116 TInt CMccRtpMediaClock::GetTimeStamp( TUint32 aKey, TUint32& aTimeStamp )
       
   117     {
       
   118     __SUBCONTROLLER( "CMccRtpMediaClock::GetTimeStamp" );
       
   119     
       
   120     TInt cell( KErrNotFound );
       
   121     
       
   122     if ( aKey != iUsedKey )
       
   123         {
       
   124         __SUBCONTROLLER_INT1( "---CMccRtpMediaClock::GetTimeStamp key changed: ", aKey )
       
   125         
       
   126         TInt err = CheckKey( aKey, cell );
       
   127         if ( err )
       
   128             {
       
   129             // if not registered, -1 is returned
       
   130             return err;
       
   131             }
       
   132         }
       
   133     
       
   134     // increment is done with previous sampling rate and hw time
       
   135     aTimeStamp = TimeStampIncrement();
       
   136     
       
   137     if ( KErrNotFound != cell )
       
   138         {
       
   139         // update current parameters
       
   140         iUsedKey = aKey;
       
   141         iSamplingFreq = iRegister[cell].iSamplingFreq;
       
   142         iHwFrametime = iRegister[cell].iHwFrametime;
       
   143         
       
   144         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::GetTimeStamp cell: ", cell )
       
   145         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::GetTimeStamp iRegister.iKey: ", iRegister[cell].iKey )
       
   146         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::GetTimeStamp iRegister.iSamplingFreq: ", iRegister[cell].iSamplingFreq )
       
   147         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::GetTimeStamp iRegister.iHwFrametime: ", iRegister[cell].iHwFrametime )
       
   148         }
       
   149     
       
   150     return KErrNone;
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // Returns the latest used rtp timestamp.
       
   155 // For 'initial keep alive' and 'during call keep alive'.
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 void CMccRtpMediaClock::GetLatestConsumedTS( TUint32& aTimeStamp )
       
   159     {
       
   160     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::GetLatestConsumedTS: ", iCurRtpTS );
       
   161     
       
   162     aTimeStamp = iCurRtpTS;
       
   163     }
       
   164 
       
   165 // ---------------------------------------------------------------------------
       
   166 // Private method
       
   167 // Designed to take care of rtp time stamp calculation
       
   168 // ---------------------------------------------------------------------------
       
   169 //
       
   170 TUint32 CMccRtpMediaClock::TimeStampIncrement()
       
   171     {
       
   172     __SUBCONTROLLER ("CMccRtpMediaClock::TimeStampIncrement" )  
       
   173     
       
   174     TTime current;
       
   175     current.UniversalTime();
       
   176     
       
   177     TTimeIntervalSeconds seconds;
       
   178     current.SecondsFrom( iPreviousTimestamp, seconds );
       
   179     
       
   180     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::TimeStampIncrement secs: ", seconds.Int() )
       
   181     
       
   182     // Note: We cannot rely that this function is called with monotonic rate.
       
   183     // Due to the fact that audio adaptation may not work with monotonic rate,
       
   184     // we must not use TTime and other variants to calculate RTP timestamps,
       
   185     // but increment the timestamp each time this function is called.
       
   186     // Thus we rely on the fact that caller knows best if the RTP mediaclock
       
   187     // timestamp should be incremented.
       
   188     // Note that if there is at least two second delay between the calls to
       
   189     // this function, then we take into account the actual time between the
       
   190     // calls. Currently we use two second limit between the calls.
       
   191     const TTimeIntervalSeconds diff( KIdleTimeStampLimitSecs );
       
   192     if ( diff < seconds )
       
   193         {
       
   194         iTimeBasedIncrement = ETrue;
       
   195         
       
   196         iCurRtpTS += TUint( seconds.Int() * iSamplingFreq );
       
   197         
       
   198         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::TimeStampIncrement timebased incr: ",
       
   199             seconds.Int() * iSamplingFreq )
       
   200         }
       
   201     else
       
   202         {
       
   203         iTimeBasedIncrement = EFalse;
       
   204         
       
   205         const TUint khzPart = iSamplingFreq / KKiloHzDivider;
       
   206         iCurRtpTS += TUint( iHwFrametime * khzPart );
       
   207         
       
   208         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::TimeStampIncrement callbased incr: ",
       
   209             iHwFrametime * khzPart )
       
   210         }
       
   211     
       
   212     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::TimeStampIncrement iCurRtpTS: ",
       
   213         iCurRtpTS )
       
   214     
       
   215     // Get the current time to make the calculation when called next.
       
   216     iPreviousTimestamp.UniversalTime();
       
   217     
       
   218     return iCurRtpTS;
       
   219     }
       
   220 
       
   221 // ---------------------------------------------------------------------------
       
   222 // Private method
       
   223 // Check used key if it is registered
       
   224 // ---------------------------------------------------------------------------
       
   225 //
       
   226 TInt CMccRtpMediaClock::CheckKey( TUint32 aKey, TInt& aCell )
       
   227     {
       
   228     __SUBCONTROLLER( "CMccRtpMediaClock::CheckKey" )
       
   229     
       
   230     const TInt count( iRegister.Count() );
       
   231     
       
   232     for( TInt i = 0; i < count; i++ )
       
   233         {
       
   234         if( iRegister[i].iKey == aKey )
       
   235             {
       
   236             __SUBCONTROLLER_INT1( "CMccRtpMediaClock::CheckKey return key cell: ", i )
       
   237             
       
   238             aCell = i;
       
   239             return KErrNone;
       
   240             }
       
   241         }
       
   242     
       
   243     __SUBCONTROLLER( "CMccRtpMediaClock::CheckKey return error KErrNotFound" )
       
   244     
       
   245     return KErrNotFound;
       
   246     }
       
   247 
       
   248 // ---------------------------------------------------------------------------
       
   249 // Removes a media format registration if found.
       
   250 // ---------------------------------------------------------------------------
       
   251 //
       
   252 void CMccRtpMediaClock::UnregisterMediaFormat( TUint32 aKey )
       
   253     {
       
   254     __SUBCONTROLLER_INT1( "CMccRtpMediaClock::UnregisterMediaFormat aKey: ", aKey )
       
   255             
       
   256     TInt cell = KErrNotFound;
       
   257     TInt err = CheckKey( aKey, cell );
       
   258     if ( KErrNone == err )
       
   259         {
       
   260         __SUBCONTROLLER_INT1( "CMccRtpMediaClock::UnregisterMediaFormat remove cell: ",
       
   261             cell )
       
   262         
       
   263         iRegister.Remove( cell );
       
   264         }
       
   265     }
       
   266 
       
   267 // ---------------------------------------------------------------------------
       
   268 // Checks whether 'timebased' or 'callback' increment has been used
       
   269 // ---------------------------------------------------------------------------
       
   270 //
       
   271 TBool CMccRtpMediaClock::TimeBasedIncrement() const
       
   272    	{
       
   273    	__SUBCONTROLLER_INT1( "CMccRtpMediaClock::TimeBasedIncrement: ", 
       
   274    	    iTimeBasedIncrement )
       
   275    	return iTimeBasedIncrement;
       
   276    	}
       
   277 
       
   278 
       
   279 // End of file