mmserv/voipaudioservices/JitterBufferUtility/src/JitterBufferImpl.cpp
changeset 53 eabc8c503852
parent 0 71ca22bcf22a
equal deleted inserted replaced
48:a493a607b5bf 53:eabc8c503852
     1 /*
     1 /*
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
     2  * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3  * All rights reserved.
     4 * This component and the accompanying materials are made available
     4  * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5  * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6  * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     8  *
     9 * Initial Contributors:
     9  * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10  * Nokia Corporation - initial contribution.
    11 *
    11  *
    12 * Contributors:
    12  * Contributors:
    13 *
    13  *
    14 * Description:  Implementation of Mcc Jitterbuffer
    14  * Description:  Implementation of Mcc Jitterbuffer
    15 *
    15  *
    16 */
    16  */
    17 
       
    18 
    17 
    19 // INCLUDE FILES
    18 // INCLUDE FILES
    20 #include <e32base.h>
    19 #include <e32base.h>
    21 #include <mmcccodecinformation.h> //codec FourCC declarations
    20 #include <mmcccodecinformation.h> //codec FourCC declarations
    22 #include "debugtracemacros.h"
    21 #include "debugtracemacros.h"
    23 #include "CngGenerator.h"
    22 #include "CngGenerator.h"
    24 #include "InternalDef.h"
    23 #include "InternalDef.h"
    25 #include "JitterBufferObserver.h"
    24 #include "JitterBufferObserver.h"
    26 #include "JitterBufferImpl.h"
    25 #include "JitterBufferImpl.h"
    27 
    26 
    28 
       
    29 // -----------------------------------------------------------------------------
    27 // -----------------------------------------------------------------------------
    30 // TJitterBufferElement::CompareSeqNum
    28 // TJitterBufferElement::CompareSeqNum
    31 // Compare SequenceNumber
    29 // Compare SequenceNumber
    32 // -----------------------------------------------------------------------------
    30 // -----------------------------------------------------------------------------
    33 //
    31 //
    34 TInt TJitterBufferElement::CompareSeqNum(const TJitterBufferElement& aElem1,
    32 TInt TJitterBufferElement::CompareSeqNum(const TJitterBufferElement& aElem1,
    35                                          const TJitterBufferElement& aElem2)
    33         const TJitterBufferElement& aElem2)
    36     {
    34     {
    37     if (aElem1.iSequenceNumber > aElem2.iSequenceNumber)
    35     if (aElem1.iSequenceNumber > aElem2.iSequenceNumber)
    38         {
    36         {
    39         return (-1);
    37         return (-1);
    40         }
    38         }
    52 // TJitterBufferElement::CompareStamp
    50 // TJitterBufferElement::CompareStamp
    53 // Compare Stamp
    51 // Compare Stamp
    54 // -----------------------------------------------------------------------------
    52 // -----------------------------------------------------------------------------
    55 //
    53 //
    56 TInt TJitterBufferElement::CompareStamp(const TJitterBufferElement& aElem1,
    54 TInt TJitterBufferElement::CompareStamp(const TJitterBufferElement& aElem1,
    57                                         const TJitterBufferElement& aElem2)
    55         const TJitterBufferElement& aElem2)
    58     {
    56     {
    59     if (aElem1.iTimeStamp > aElem2.iTimeStamp)
    57     if (aElem1.iTimeStamp > aElem2.iTimeStamp)
    60         {
    58         {
    61         return (-1);
    59         return (-1);
    62         }
    60         }
    74 // CVoIPJitterBufferImpl::CVoIPJitterBufferImpl
    72 // CVoIPJitterBufferImpl::CVoIPJitterBufferImpl
    75 // C++ default constructor can NOT contain any code, that might leave.
    73 // C++ default constructor can NOT contain any code, that might leave.
    76 // -----------------------------------------------------------------------------
    74 // -----------------------------------------------------------------------------
    77 //
    75 //
    78 CVoIPJitterBufferImpl::CVoIPJitterBufferImpl(MJitterBufferObserver* aObserver) :
    76 CVoIPJitterBufferImpl::CVoIPJitterBufferImpl(MJitterBufferObserver* aObserver) :
    79     iBufStampSorter(TLinearOrder<TJitterBufferElement>(
    77     iBufStampSorter(TLinearOrder<TJitterBufferElement> (
    80                     TJitterBufferElement::CompareStamp)),
    78             TJitterBufferElement::CompareStamp)),
    81     iBufSequenceSorter(TLinearOrder<TJitterBufferElement>(
    79     iBufSequenceSorter(TLinearOrder<TJitterBufferElement> (
    82                     TJitterBufferElement::CompareSeqNum))
    80             TJitterBufferElement::CompareSeqNum))
    83     {
    81     {
    84     iObserver = aObserver;
    82     iObserver = aObserver;
    85     iTonePlayTime.UniversalTime();
    83     iTonePlayTime.UniversalTime();
    86     iSampleRate = KDefaultSampleRateInkHz;
    84     iSampleRate = KDefaultSampleRateInkHz;
    87     iPlay = EFalse;
    85     iPlay = EFalse;
    92 // CVoIPJitterBufferImpl::NewL
    90 // CVoIPJitterBufferImpl::NewL
    93 // Static constructor.
    91 // Static constructor.
    94 // -----------------------------------------------------------------------------
    92 // -----------------------------------------------------------------------------
    95 //
    93 //
    96 CVoIPJitterBufferImpl* CVoIPJitterBufferImpl::NewL(
    94 CVoIPJitterBufferImpl* CVoIPJitterBufferImpl::NewL(
    97                                               MJitterBufferObserver* aObserver)
    95         MJitterBufferObserver* aObserver)
    98     {
    96     {
    99     CVoIPJitterBufferImpl* self = new(ELeave) CVoIPJitterBufferImpl(aObserver);
    97     CVoIPJitterBufferImpl* self = new (ELeave) CVoIPJitterBufferImpl(aObserver);
   100     CleanupStack::PushL(self);
    98     CleanupStack::PushL(self);
   101     self->ConstructL();
    99     self->ConstructL();
   102     CleanupStack::Pop(self);
   100     CleanupStack::Pop(self);
   103     return self;
   101     return self;
   104     }
   102     }
   143 // CVoIPJitterBufferImpl::SetupL
   141 // CVoIPJitterBufferImpl::SetupL
   144 // Setup Jitter buffer
   142 // Setup Jitter buffer
   145 // -----------------------------------------------------------------------------
   143 // -----------------------------------------------------------------------------
   146 //
   144 //
   147 void CVoIPJitterBufferImpl::SetupL(const TFourCC aCodec,
   145 void CVoIPJitterBufferImpl::SetupL(const TFourCC aCodec,
   148                                    const TVoIPJBConfig& aJBConfig)
   146         const TVoIPJBConfig& aJBConfig)
   149     {
   147     {
   150     TRACE_PRN_FN_ENT;
   148     TRACE_PRN_FN_ENT;
   151 
   149 
   152     __ASSERT_ALWAYS(aJBConfig.iJitterLatency, User::Leave(KErrArgument));
   150     __ASSERT_ALWAYS(aJBConfig.iJitterLatency, User::Leave(KErrArgument));
   153     __ASSERT_ALWAYS(aJBConfig.iJBBufferLength, User::Leave(KErrArgument));
   151     __ASSERT_ALWAYS(aJBConfig.iJBBufferLength, User::Leave(KErrArgument));
   159     iJBConfig = aJBConfig;
   157     iJBConfig = aJBConfig;
   160 
   158 
   161     if (iJBConfig.iJBInactivityTimeOut)
   159     if (iJBConfig.iJBInactivityTimeOut)
   162         {
   160         {
   163         if ((iJBConfig.iJBPlayToneFrequency > 0) &&
   161         if ((iJBConfig.iJBPlayToneFrequency > 0) &&
   164             (iJBConfig.iJBPlayToneDuration > 0))
   162                 (iJBConfig.iJBPlayToneDuration > 0))
   165             {
   163             {
   166             iPlayToneInterval = iJBConfig.iJBPlayToneTimeout;
   164             iPlayToneInterval = iJBConfig.iJBPlayToneTimeout;
   167             iPlay = ETrue;
   165             iPlay = ETrue;
   168             }
   166             }
   169         }
   167         }
   178     else if (aCodec == KMccFourCCIdG711)
   176     else if (aCodec == KMccFourCCIdG711)
   179         {
   177         {
   180         // G.711 is configured dynamically. Take voip headerlength also into
   178         // G.711 is configured dynamically. Take voip headerlength also into
   181         // account. G.711 hwframetime is in milliseconds, so need to multiply.
   179         // account. G.711 hwframetime is in milliseconds, so need to multiply.
   182         iFrameSize = (iJBConfig.iSampleInterval * KDefaultSampleRateInkHz) +
   180         iFrameSize = (iJBConfig.iSampleInterval * KDefaultSampleRateInkHz) +
   183                      KVoIPHeaderLength;
   181                 KVoIPHeaderLength;
   184         iSampleInterval = 0;
   182         iSampleInterval = 0;
   185 
   183 
   186         // In case of G.711 codec dynamic configuration, we may need to double
   184         // In case of G.711 codec dynamic configuration, we may need to double
   187         // the jitter buffer length if HW frame time is changed from 20ms to
   185         // the jitter buffer length if HW frame time is changed from 20ms to
   188         // 10ms.
   186         // 10ms.
   228 
   226 
   229     iBuffer.Reset();
   227     iBuffer.Reset();
   230 
   228 
   231     // Calculate needed elements
   229     // Calculate needed elements
   232     iBufferLength = iJBConfig.iJBBufferLength * bufLenMultiplier;
   230     iBufferLength = iJBConfig.iJBBufferLength * bufLenMultiplier;
   233     
   231 
   234     if (iJBConfig.iJBThreshold >= iBufferLength)
   232     if (iJBConfig.iJBThreshold >= iBufferLength)
   235     	{
   233         {
   236     	// adjust threshold size (no need to leave here)
   234         // adjust threshold size (no need to leave here)
   237     	iJBConfig.iJBThreshold = iBufferLength / 2;
   235         iJBConfig.iJBThreshold = iBufferLength / 2;
   238     	}
   236         }
   239 
   237 
   240     // If the difference between buffer length and threshold is less than 10
   238     // If the difference between buffer length and threshold is less than 10
   241     // increase buffer length, so the differences is 10. This helps handle
   239     // increase buffer length, so the differences is 10. This helps handle
   242     // buffer overflow more easily.
   240     // buffer overflow more easily.
   243     CheckThresholdBufferLength(iBufferLength, iJBConfig.iJBThreshold);
   241     CheckThresholdBufferLength(iBufferLength, iJBConfig.iJBThreshold);
   282 // -----------------------------------------------------------------------------
   280 // -----------------------------------------------------------------------------
   283 // CVoIPJitterBufferImpl::ResetBufferL
   281 // CVoIPJitterBufferImpl::ResetBufferL
   284 // Reset Jitter Buffer
   282 // Reset Jitter Buffer
   285 // -----------------------------------------------------------------------------
   283 // -----------------------------------------------------------------------------
   286 //
   284 //
   287 
       
   288 void CVoIPJitterBufferImpl::ResetBuffer(TBool aPlayTone)
   285 void CVoIPJitterBufferImpl::ResetBuffer(TBool aPlayTone)
   289     {
   286     {
   290     TRACE_PRN_FN_ENT;
   287     TRACE_PRN_FN_ENT;
   291 
   288 
   292     for (TInt i = 0; i < iBufferLength; i++)
   289     for (TInt i = 0; i < iBufferLength; i++)
   318     newElement.iDataFrame = buf;
   315     newElement.iDataFrame = buf;
   319     newElement.iSequenceNumber = -1;
   316     newElement.iSequenceNumber = -1;
   320     newElement.iTimeStamp = -1;
   317     newElement.iTimeStamp = -1;
   321     iBuffer.AppendL(newElement);
   318     iBuffer.AppendL(newElement);
   322     CleanupStack::Pop(buf);
   319     CleanupStack::Pop(buf);
   323     
   320 
   324     iBufferLength++;
   321     iBufferLength++;
   325 
   322 
   326     // Insert one NO_DATA frame into the audio stream, so the jitterbuffer has
   323     // Insert one NO_DATA frame into the audio stream, so the jitterbuffer has
   327     // the possibility to grow at least one frame from the current size. If
   324     // the possibility to grow at least one frame from the current size. If
   328     // the current playout threshold is zero, then there is ongoing playback or
   325     // the current playout threshold is zero, then there is ongoing playback or
   435         }
   432         }
   436 
   433 
   437     TRACE_PRN_FN_EXT;
   434     TRACE_PRN_FN_EXT;
   438     }
   435     }
   439 
   436 
       
   437 #ifdef __FEATURE_NOT_SUPPORTED__
   440 // -----------------------------------------------------------------------------
   438 // -----------------------------------------------------------------------------
   441 // CVoIPJitterBufferImpl::CalculateDelay
   439 // CVoIPJitterBufferImpl::CalculateDelay
   442 // Calculates the current jitter buffer playback
   440 // Calculates the current jitter buffer playback
   443 // -----------------------------------------------------------------------------
   441 // -----------------------------------------------------------------------------
   444 //
   442 //
   445 TTimeIntervalMicroSeconds32 CVoIPJitterBufferImpl::CalculateDelay() const
   443 TTimeIntervalMicroSeconds32 CVoIPJitterBufferImpl::CalculateDelay() const
   446     {
   444     {
   447     TTimeIntervalMicroSeconds32 delay =
   445     TTimeIntervalMicroSeconds32 delay = iJBConfig.iJitterLatency *
   448                                 iJBConfig.iJitterLatency * iPacketsInBuffer;
   446             iPacketsInBuffer;
   449 
   447 
   450 //    TRACE_PRN_N1(_L("JB-CalculateDelay-> Delay [%d]"), delay);
   448     //TRACE_PRN_N1(_L("JB-CalculateDelay-> Delay [%d]"), delay);
   451 
   449 
   452     return delay;
   450     return delay;
   453     }
   451     }
       
   452 #endif //__FEATURE_NOT_SUPPORTED__
   454 
   453 
   455 // -----------------------------------------------------------------------------
   454 // -----------------------------------------------------------------------------
   456 // CVoIPJitterBufferImpl::AddDataFrame
   455 // CVoIPJitterBufferImpl::AddDataFrame
   457 // Adds audio frame into the jitter buffer
   456 // Adds audio frame into the jitter buffer
   458 // -----------------------------------------------------------------------------
   457 // -----------------------------------------------------------------------------
   487     //  3.1 DTX start packet may be lost
   486     //  3.1 DTX start packet may be lost
   488     //  3.2 DTX UPDATE packet may be lost (if used)
   487     //  3.2 DTX UPDATE packet may be lost (if used)
   489     //
   488     //
   490 
   489 
   491     TUint index = FindLargestSeqNum();
   490     TUint index = FindLargestSeqNum();
   492         
   491 
   493     if (iLastPlayedSeqNum < KMaxSeqNumber - iSeqNumIncrement)
   492     if (iLastPlayedSeqNum < KMaxSeqNumber - iSeqNumIncrement)
   494         {
   493         {
   495         iIsWrappedAround = IsSeqNumWrappedAround(iLargestSeqNum,
   494         iIsWrappedAround = IsSeqNumWrappedAround(iLargestSeqNum,
   496                                                  iCurrentSeqNum);    
   495                 iCurrentSeqNum);
   497         }
   496         }
   498     else
   497     else
   499         {
   498         {
   500         // If the last played frame was larger than the current largest
   499         // If the last played frame was larger than the current largest
   501         // in JB we are most likely running in the wrap-around mode.
   500         // in JB we are most likely running in the wrap-around mode.
   502         iIsWrappedAround = IsSeqNumWrappedAround(iLastPlayedSeqNum,
   501         iIsWrappedAround = IsSeqNumWrappedAround(iLastPlayedSeqNum,
   503                                                  iLargestSeqNum);
   502                 iLargestSeqNum);
   504         }
   503         }
   505 
   504 
   506     if (iIsWrappedAround)
   505     if (iIsWrappedAround)
   507         {
   506         {
   508         iLastPlayedSeqNum = -1;
   507         iLastPlayedSeqNum = -1;
   511     TRACE_PRN_N1(_L("JB-> [ADD] LARGEST IN  [%d]"), TInt32(iLargestSeqNum));
   510     TRACE_PRN_N1(_L("JB-> [ADD] LARGEST IN  [%d]"), TInt32(iLargestSeqNum));
   512     TRACE_PRN_N1(_L("JB-> [ADD] THIS FRAME  [%d]"), TInt32(iCurrentSeqNum));
   511     TRACE_PRN_N1(_L("JB-> [ADD] THIS FRAME  [%d]"), TInt32(iCurrentSeqNum));
   513     TRACE_PRN_N1(_L("JB-> [ADD] LAST PLAYED [%d]"), TInt32(iLastPlayedSeqNum));
   512     TRACE_PRN_N1(_L("JB-> [ADD] LAST PLAYED [%d]"), TInt32(iLastPlayedSeqNum));
   514     TRACE_PRN_N1(_L("JB-> [ADD] PACKETS [%d]"), iPacketsInBuffer);
   513     TRACE_PRN_N1(_L("JB-> [ADD] PACKETS [%d]"), iPacketsInBuffer);
   515 
   514 
   516     iDataBuffer = static_cast<CMMFDataBuffer*>(aDataBuffer);
   515     iDataBuffer = static_cast<CMMFDataBuffer*> (aDataBuffer);
   517 
   516 
   518     if (iCurrentSeqNum > iLastPlayedSeqNum)
   517     if (iCurrentSeqNum > iLastPlayedSeqNum)
   519         {
   518         {
   520         if (IsFull())
   519         if (IsFull())
   521             {
   520             {
   559                 {
   558                 {
   560                 TRACE_PRN_N(_L("JB-> [ADD] BUFFER EMPTY - Tone NOT played"));
   559                 TRACE_PRN_N(_L("JB-> [ADD] BUFFER EMPTY - Tone NOT played"));
   561                 TRACE_PRN_N1(_L("JB-> [ADD] Interval Tm [%d]"), interval.Int());
   560                 TRACE_PRN_N1(_L("JB-> [ADD] Interval Tm [%d]"), interval.Int());
   562                 }
   561                 }
   563 
   562 
   564             // No point to run at 0 threshold; restore the original 
   563             // No point to run at 0 threshold; restore the original
   565             // settings and rebuffer. 
   564             // settings and rebuffer.
   566             iCurrentPlayThreshold = iOriginalPlayThreshold;
   565             iCurrentPlayThreshold = iOriginalPlayThreshold;
   567 
   566 
   568             const TInt64 nextGetSeqNum(iLastPlayedSeqNum + iSeqNumIncrement);
   567             const TInt64 nextGetSeqNum(iLastPlayedSeqNum + iSeqNumIncrement);
   569             const TInt64 frameSeq(iDataBuffer->FrameNumber());
   568             const TInt64 frameSeq(iDataBuffer->FrameNumber());
   570 
   569 
   594         {
   593         {
   595         iNumOfLateFrames++;
   594         iNumOfLateFrames++;
   596         aDataBuffer->SetStatus(EAvailable);
   595         aDataBuffer->SetStatus(EAvailable);
   597         TRACE_PRN_N(_L("JB-> [ADD] TOO LATE"));
   596         TRACE_PRN_N(_L("JB-> [ADD] TOO LATE"));
   598         }
   597         }
   599     
   598 
   600     return KErrNone;
   599     return KErrNone;
   601     }
   600     }
   602 
   601 
   603 // -----------------------------------------------------------------------------
   602 // -----------------------------------------------------------------------------
   604 // CVoIPJitterBufferImpl::GetDataFrame
   603 // CVoIPJitterBufferImpl::GetDataFrame
   610     if (aBuffer == NULL)
   609     if (aBuffer == NULL)
   611         {
   610         {
   612         return KErrNotReady;
   611         return KErrNotReady;
   613         }
   612         }
   614 
   613 
   615     iDataBuffer = static_cast<CMMFDataBuffer*>(aBuffer);
   614     iDataBuffer = static_cast<CMMFDataBuffer*> (aBuffer);
   616     TDes8& playBuffer(iDataBuffer->Data());
   615     TDes8& playBuffer(iDataBuffer->Data());
   617     iFramesPlayed++;
   616     iFramesPlayed++;
   618 
   617 
   619     if (IsEmpty())
   618     if (IsEmpty())
   620         {
   619         {
   621         // Buffer is empty, so we need to generate CN frames. During DTX period
   620         // Buffer is empty, so we need to generate CN frames. During DTX period
   622         // this is where we'll end up. If we are empty because of DTX period,
   621         // this is where we'll end up. If we are empty because of DTX period,
   623         // the CN generator will do the error concealment.
   622         // the CN generator will do the error concealment.
   624         TRACE_PRN_N(_L("JB-> [GET] BUFFER EMPTY"));
   623         TRACE_PRN_N(_L("JB-> [GET] BUFFER EMPTY"));
   625 
   624 
   626         iCNGenerator->GenerateSidPacket(playBuffer, iDataBuffer->RequestSize());
   625         iCNGenerator->GenerateSidPacket(playBuffer,
   627         
   626                 iDataBuffer->RequestSize());
       
   627 
   628         // Used for talkburst; when talk-burst is over, reset buffer
   628         // Used for talkburst; when talk-burst is over, reset buffer
   629         // and sequence number
   629         // and sequence number
   630         if (iJBConfig.iJBInactivityTimeOut > 0 && iInactivityTime >= 0)
   630         if (iJBConfig.iJBInactivityTimeOut > 0 && iInactivityTime >= 0)
   631             {
   631             {
   632             // Currently it is only used for AMR codec.
   632             // Currently it is only used for AMR codec.
   633             iInactivityTime += iSampleInterval;
   633             iInactivityTime += iSampleInterval;
   634 
   634 
   635             if (iInactivityTime >= iJBConfig.iJBInactivityTimeOut)
   635             if (iInactivityTime >= iJBConfig.iJBInactivityTimeOut)
   636                 {
   636                 {
   637                 TRACE_PRN_N1(_L("JB-> [GET] Inactivity Time Detected [%d]"),
   637                 TRACE_PRN_N1(_L("JB-> [GET] Inactivity Time Detected [%d]"),
   638                              iInactivityTime);
   638                         iInactivityTime);
   639                 iInactivityTime = -1;
   639                 iInactivityTime = -1;
   640                 ResetBuffer();
   640                 ResetBuffer();
   641                 }
   641                 }
   642             }
   642             }
   643         }
   643         }
   647         if (iPacketsInBuffer < iCurrentPlayThreshold)
   647         if (iPacketsInBuffer < iCurrentPlayThreshold)
   648             {
   648             {
   649             // Give comfort noise when we are buffering before playback starts
   649             // Give comfort noise when we are buffering before playback starts
   650             TRACE_PRN_N(_L("JB-> [GET] THRESHOLD NOT REACHED"));
   650             TRACE_PRN_N(_L("JB-> [GET] THRESHOLD NOT REACHED"));
   651             iCNGenerator->GenerateSidPacket(playBuffer,
   651             iCNGenerator->GenerateSidPacket(playBuffer,
   652                                             iDataBuffer->RequestSize());
   652                     iDataBuffer->RequestSize());
   653             }
   653             }
   654         else
   654         else
   655             {
   655             {
   656             // Reset threshold, so we can  play current talk-spurt till the
   656             // Reset threshold, so we can  play current talk-spurt till the
   657             // end without affecting speech quality. This means that we will
   657             // end without affecting speech quality. This means that we will
   658             // play the buffer until it is empty. After that, it is either
   658             // play the buffer until it is empty. After that, it is either
   659             // DTX period or packet loss.
   659             // DTX period or packet loss.
   660             iCurrentPlayThreshold = 0;
   660             iCurrentPlayThreshold = 0;
   661 
   661 
   662             // The actual sequence number which is in the buffer
   662             // The actual sequence number which is in the buffer
   663 //            const TInt64 frameToPlay(
   663             //const TInt64 frameToPlay(
   664 //                         iBuffer[iPacketsInBuffer - 1].iSequenceNumber);
   664             //iBuffer[iPacketsInBuffer - 1].iSequenceNumber);
   665 
   665 
   666             TRACE_PRN_N1(_L("JB-> [GET] FRAME TO PLAY [%d]"),
   666             TRACE_PRN_N1(_L("JB-> [GET] FRAME TO PLAY [%d]"),
   667                          TInt32(iBuffer[iPacketsInBuffer - 1].iSequenceNumber));
   667                     TInt32(iBuffer[iPacketsInBuffer - 1].iSequenceNumber));
   668             TRACE_PRN_N1(_L("JB-> [GET] LAST PLAYED   [%d]"),
   668             TRACE_PRN_N1(_L("JB-> [GET] LAST PLAYED   [%d]"),
   669                          TInt32(iLastPlayedSeqNum));
   669                     TInt32(iLastPlayedSeqNum));
   670             TRACE_PRN_N1(_L("JB-> [GET] PACKETS [%d]"), iPacketsInBuffer);
   670             TRACE_PRN_N1(_L("JB-> [GET] PACKETS [%d]"), iPacketsInBuffer);
   671 
   671 
   672             // Get next in order frame to play
   672             // Get next in order frame to play
   673             TJitterBufferElement& jbElement = iBuffer[iPacketsInBuffer - 1];
   673             TJitterBufferElement& jbElement = iBuffer[iPacketsInBuffer - 1];
   674 
   674 
   675             if (playBuffer.MaxLength() >= jbElement.iDataFrame->Data().Length())
   675             if (playBuffer.MaxLength() >=
       
   676                     jbElement.iDataFrame->Data().Length())
   676                 {
   677                 {
   677                 playBuffer.Copy(jbElement.iDataFrame->Data());
   678                 playBuffer.Copy(jbElement.iDataFrame->Data());
   678                 }
   679                 }
   679             else
   680             else
   680                 {
   681                 {
   681                 TRACE_PRN_N1(_L("JB-> [GET] ERROR: BUFFER TOO SMALL [%d]"),
   682                 TRACE_PRN_N1(_L("JB-> [GET] ERROR: BUFFER TOO SMALL [%d]"),
   682                              playBuffer.MaxLength());
   683                         playBuffer.MaxLength());
   683 
   684 
   684                 iCNGenerator->GenerateSidPacket(playBuffer,
   685                 iCNGenerator->GenerateSidPacket(playBuffer,
   685                                                 iDataBuffer->RequestSize());
   686                         iDataBuffer->RequestSize());
   686                 }
   687                 }
   687 
   688 
   688             iLastPlayedSeqNum = jbElement.iSequenceNumber;
   689             iLastPlayedSeqNum = jbElement.iSequenceNumber;
   689             jbElement.iSequenceNumber = -1;
   690             jbElement.iSequenceNumber = -1;
   690             jbElement.iTimeStamp = -1;
   691             jbElement.iTimeStamp = -1;
   691             iPacketsInBuffer--;
   692             iPacketsInBuffer--;
   692 
   693 
   693             // Reset inactivity timeout timer
   694             // Reset inactivity timeout timer
   694             iInactivityTime = 0;
   695             iInactivityTime = 0;
   695 
   696 
       
   697 #ifdef __FEATURE_NOT_SUPPORTED__
   696             // Try to lead new buffer to DTX period
   698             // Try to lead new buffer to DTX period
   697             iCNGenerator->DoDtxDecision(playBuffer);
   699             iCNGenerator->DoDtxDecision(playBuffer);
   698             }
   700 #endif //__FEATURE_NOT_SUPPORTED__
   699         }
   701             }
   700     
   702         }
       
   703 
   701     return KErrNone;
   704     return KErrNone;
   702     }
   705     }
   703 
   706 
   704 // -----------------------------------------------------------------------------
   707 // -----------------------------------------------------------------------------
   705 // CVoIPJitterBufferImpl::FindLargestSeqNum
   708 // CVoIPJitterBufferImpl::FindLargestSeqNum
   730 // CVoIPJitterBufferImpl::InsertBufferElement
   733 // CVoIPJitterBufferImpl::InsertBufferElement
   731 // Insert Buffer Element
   734 // Insert Buffer Element
   732 // -----------------------------------------------------------------------------
   735 // -----------------------------------------------------------------------------
   733 //
   736 //
   734 void CVoIPJitterBufferImpl::InsertBufferElement(const TDesC8& aBuffer,
   737 void CVoIPJitterBufferImpl::InsertBufferElement(const TDesC8& aBuffer,
   735                                                 TInt64 aLargestSeqNum)
   738         TInt64 aLargestSeqNum)
   736     {
   739     {
   737 //    TRACE_PRN_FN_ENT;
   740     /* if (aBuffer.Length() == 0 || aBuffer.Length() > iFrameSize)
   738 
       
   739 /*    if (aBuffer.Length() == 0 || aBuffer.Length() > iFrameSize)
       
   740         {
   741         {
   741         TRACE_PRN_N(_L("JB->INVALID DATA, IGNORING"));
   742         TRACE_PRN_N(_L("JB->INVALID DATA, IGNORING"));
   742         return;
   743         return;
   743         }*/
   744         }*/
   744 
   745 
   745     const TInt len(BufferLength());
   746     const TInt len(BufferLength());
   746 
   747 
   747     if (iIsWrappedAround)
   748     if (iIsWrappedAround)
   748         {
   749         {
   749         iBuffer[len-1].iDataFrame->Data().Copy(aBuffer);
   750         iBuffer[len - 1].iDataFrame->Data().Copy(aBuffer);
   750         iBuffer[len-1].iSequenceNumber = iCurrentSeqNum;
   751         iBuffer[len - 1].iSequenceNumber = iCurrentSeqNum;
   751 
   752 
   752         for (TInt i = 0; i < len; i++)
   753         for (TInt i = 0; i < len; i++)
   753             {
   754             {
   754             if (iBuffer[i].iTimeStamp > aLargestSeqNum)
   755             if (iBuffer[i].iTimeStamp > aLargestSeqNum)
   755                 {
   756                 {
   756                 aLargestSeqNum = iBuffer[i].iTimeStamp;
   757                 aLargestSeqNum = iBuffer[i].iTimeStamp;
   757                 }
   758                 }
   758             }
   759             }
   759 
   760 
   760         iBuffer[len-1].iTimeStamp = aLargestSeqNum + 1;
   761         iBuffer[len - 1].iTimeStamp = aLargestSeqNum + 1;
   761         iBuffer.Sort(iBufStampSorter);
   762         iBuffer.Sort(iBufStampSorter);
   762         iLastPlayedSeqNum = -1;
   763         iLastPlayedSeqNum = -1;
   763         }
   764         }
   764     else
   765     else
   765         {
   766         {
   766         iBuffer[len-1].iDataFrame->Data().Copy(aBuffer);
   767         iBuffer[len - 1].iDataFrame->Data().Copy(aBuffer);
   767         iBuffer[len-1].iSequenceNumber = iCurrentSeqNum;
   768         iBuffer[len - 1].iSequenceNumber = iCurrentSeqNum;
   768         iBuffer[len-1].iTimeStamp = iCurrentSeqNum - BufferLength();
   769         iBuffer[len - 1].iTimeStamp = iCurrentSeqNum - BufferLength();
   769         iBuffer.Sort(iBufSequenceSorter);
   770         iBuffer.Sort(iBufSequenceSorter);
   770         }
   771         }
   771 
   772 
   772     iPacketsInBuffer++;
   773     iPacketsInBuffer++;
   773 
       
   774 //    TRACE_PRN_FN_EXT;
       
   775     }
   774     }
   776 
   775 
   777 // -----------------------------------------------------------------------------
   776 // -----------------------------------------------------------------------------
   778 // CVoIPJitterBufferImpl::BufferLength()
   777 // CVoIPJitterBufferImpl::BufferLength()
   779 // Return buffer length.
   778 // Return buffer length.
   782 TInt CVoIPJitterBufferImpl::BufferLength() const
   781 TInt CVoIPJitterBufferImpl::BufferLength() const
   783     {
   782     {
   784     return iBufferLength;
   783     return iBufferLength;
   785     }
   784     }
   786 
   785 
       
   786 #ifdef __FEATURE_NOT_SUPPORTED__
   787 // -----------------------------------------------------------------------------
   787 // -----------------------------------------------------------------------------
   788 // CVoIPJitterBufferImpl::PacketCount()
   788 // CVoIPJitterBufferImpl::PacketCount()
   789 // Return number of packets that are currently in the buffer.
   789 // Return number of packets that are currently in the buffer.
   790 // -----------------------------------------------------------------------------
   790 // -----------------------------------------------------------------------------
   791 //
   791 //
   792 TInt CVoIPJitterBufferImpl::PacketCount() const
   792 TInt CVoIPJitterBufferImpl::PacketCount() const
   793     {
   793     {
   794     return iPacketsInBuffer;
   794     return iPacketsInBuffer;
   795     }
   795     }
       
   796 #endif //__FEATURE_NOT_SUPPORTED__
   796 
   797 
   797 // -----------------------------------------------------------------------------
   798 // -----------------------------------------------------------------------------
   798 // CVoIPJitterBufferImpl::IsFull()
   799 // CVoIPJitterBufferImpl::IsFull()
   799 // Return:    True if full
   800 // Return:    True if full
   800 //            False if not full
   801 //            False if not full
   824 // This is because of network packet loss, where there might be gaps between
   825 // This is because of network packet loss, where there might be gaps between
   825 // frame sequence numbers.
   826 // frame sequence numbers.
   826 // -----------------------------------------------------------------------------
   827 // -----------------------------------------------------------------------------
   827 //
   828 //
   828 TBool CVoIPJitterBufferImpl::IsSeqNumWrappedAround(TInt64 aSeqNum1,
   829 TBool CVoIPJitterBufferImpl::IsSeqNumWrappedAround(TInt64 aSeqNum1,
   829                                                    TInt64 aSeqNum2) const
   830         TInt64 aSeqNum2) const
   830     {
   831     {
   831     TBool status = EFalse;
   832     TBool status = EFalse;
   832 
   833 
   833     if (aSeqNum1 >= (KMaxSeqNumber - iSeqNumIncrement) &&
   834     if (aSeqNum1 >= (KMaxSeqNumber - iSeqNumIncrement) &&
   834         aSeqNum2 <= (iBufferLength * iSeqNumIncrement))
   835             aSeqNum2 <= (iBufferLength * iSeqNumIncrement))
   835         {
   836         {
   836         TRACE_PRN_N(_L("JB-> SEQUENCE WRAPPED-AROUND"));
   837         TRACE_PRN_N(_L("JB-> SEQUENCE WRAPPED-AROUND"));
   837         status = ETrue;
   838         status = ETrue;
   838         }
   839         }
   839 
   840 
   840     return status;
   841     return status;
   841     }
   842     }
   842 
   843 
       
   844 #ifdef __FEATURE_NOT_SUPPORTED__
   843 // -----------------------------------------------------------------------------
   845 // -----------------------------------------------------------------------------
   844 // CVoIPJitterBufferImpl::GenerateStatistics
   846 // CVoIPJitterBufferImpl::GenerateStatistics
   845 // Generates the statistics from the jitterbuffer
   847 // Generates the statistics from the jitterbuffer
   846 // -----------------------------------------------------------------------------
   848 // -----------------------------------------------------------------------------
   847 //
   849 //
   848 void CVoIPJitterBufferImpl::GenerateStatistics(/*TJBStats& aStats*/) const
   850 void CVoIPJitterBufferImpl::GenerateStatistics(/*TJBStats& aStats*/) const
   849     {/*
   851     {
   850     aStats.iFramesReceived = iFramesReceived;
   852     aStats.iFramesReceived = iFramesReceived;
   851     aStats.iBufferLength = iBufferLength;
   853     aStats.iBufferLength = iBufferLength;
   852     aStats.iFramesInBuffer = iPacketsInBuffer;
   854     aStats.iFramesInBuffer = iPacketsInBuffer;
   853     aStats.iFrameLoss = iFramesLost;
   855     aStats.iFrameLoss = iFramesLost;
   854     aStats.iLateFrames = iNumOfLateFrames;
   856     aStats.iLateFrames = iNumOfLateFrames;
   855     aStats.iFramesRemoved = iFramesRemoved;
   857     aStats.iFramesRemoved = iFramesRemoved;
   856     aStats.iFramesPlayed = iFramesPlayed;*/
   858     aStats.iFramesPlayed = iFramesPlayed;
   857     }
   859     }
       
   860 #endif //__FEATURE_NOT_SUPPORTED__
   858 
   861 
   859 // -----------------------------------------------------------------------------
   862 // -----------------------------------------------------------------------------
   860 // CVoIPJitterBufferImpl::CheckThresholdBufferLength
   863 // CVoIPJitterBufferImpl::CheckThresholdBufferLength
   861 // -----------------------------------------------------------------------------
   864 // -----------------------------------------------------------------------------
   862 //
   865 //
   863 void CVoIPJitterBufferImpl::CheckThresholdBufferLength(TInt& aBufferLength,
   866 void CVoIPJitterBufferImpl::CheckThresholdBufferLength(TInt& aBufferLength,
   864                                                        TInt aTreshhold) const
   867         TInt aTreshhold) const
   865     {
   868     {
   866     const TInt numTen = 10;
   869     const TInt numTen = 10;
   867 
   870 
   868     if ((aBufferLength - aTreshhold) < numTen)
   871     if ((aBufferLength - aTreshhold) < numTen)
   869         {
   872         {
   870         aBufferLength = aTreshhold + numTen;
   873         aBufferLength = aTreshhold + numTen;
   871         }
   874         }
   872     }
   875     }
   873 
   876 
   874 
       
   875 //  End of File
   877 //  End of File
   876 
   878