bluetoothengine/btaudiostreamer/src/btaudiostreamsendersbc.cpp
changeset 0 f63038272f30
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2005 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:  Contains an implementation of CBTAudioStreamSenderSBC class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "btaudiostreamsendersbc.h"
       
    20 #include "btaudiostreamerdebug.h" 
       
    21 
       
    22 const TInt KA2DPMediaPacketHeaderLength = 1; 
       
    23 const TInt KA2DPMediaPacketHeaderIndex = 0; 
       
    24 const TInt KRTPHeaderLength = 12; 
       
    25 
       
    26 // ======== MEMBER FUNCTIONS ========
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // Constructor. 
       
    30 // ---------------------------------------------------------------------------
       
    31 //
       
    32 CBTAudioStreamSenderSBC::CBTAudioStreamSenderSBC(MBTAudioStreamSenderObserver& aObserver, RRtpSession& aSession): 
       
    33         CBTAudioStreamSender(aObserver, aSession) 
       
    34     {
       
    35     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CBTAudioStreamSenderSBC() ->")));
       
    36     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CBTAudioStreamSenderSBC() <-")));
       
    37     }
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // Factory method.
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 /*static*/ CBTAudioStreamSenderSBC* CBTAudioStreamSenderSBC::NewL(MBTAudioStreamSenderObserver& aObserver, RRtpSession& aSession)
       
    44     {
       
    45     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::NewL() ->")));
       
    46 
       
    47     CBTAudioStreamSenderSBC* self = new (ELeave) CBTAudioStreamSenderSBC(aObserver, aSession);
       
    48     CleanupStack::PushL(self);
       
    49     self->ConstructL();
       
    50     CleanupStack::Pop(self);
       
    51     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::NewL() <-")));
       
    52     return self;
       
    53     }
       
    54 
       
    55 // ---------------------------------------------------------------------------
       
    56 // Destructor. 
       
    57 // ---------------------------------------------------------------------------
       
    58 //
       
    59 CBTAudioStreamSenderSBC::~CBTAudioStreamSenderSBC() 
       
    60     {
       
    61     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::~CBTAudioStreamSenderSBC() ->")));
       
    62     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::~CBTAudioStreamSenderSBC() <-")));
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // From class CBTAudioStreamSender.
       
    67 // This method stores the frames to the frame buffer and 
       
    68 // when we have enough frames. 
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 TInt CBTAudioStreamSenderSBC::AddHeaderToSendPacket(TPtr8& aPayloadDesC) 
       
    72     {
       
    73     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::AddHeaderToSendPacket() ->")));
       
    74     aPayloadDesC[KA2DPMediaPacketHeaderIndex] = iNumOfFramesInSendPacket; 
       
    75     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::AddHeaderToSendPacket() <-")));
       
    76     return KErrNone; 
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // From class CBTAudioStreamSender.
       
    81 // This method stores the frames to the frame buffer and 
       
    82 // when we have enough frames. 
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 TInt CBTAudioStreamSenderSBC::AddBufferToSendPacket(const TDesC8& aBuffer) 
       
    86     {
       
    87     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::AddBufferToSendPacket() ->")));
       
    88     // Copy data from the buffer to the outgoing packet. 
       
    89     // The return code means how many frames can still fit in the SendPacket. 
       
    90     //     - If there's more space, the value > 0. In this case we need more data. 
       
    91     //  - If the buffer is full and all data was consumed, the value == 0. In this case the packet must be sent. 
       
    92     //     - If the buffer is full and all data didn't fit in it, the value < 0. The packet must be sent and this method called again with the same frame. 
       
    93 
       
    94     // Calculate how many frames there's left in the buffer. Note that iFrameLength must always be greater than zero. 
       
    95     TInt numOfFramesLeftInBuffer = (aBuffer.Length() / iFrameLength) - iNumOfFramesAlreadyMoved ; 
       
    96 
       
    97     // If the whole buffer can fit in packet, move it completely, otherwise move as many frames as can fit. 
       
    98     TInt numOfFramesToMove = numOfFramesLeftInBuffer <= iMaxNumOfFrames - iNumOfFramesInSendPacket ? 
       
    99                             numOfFramesLeftInBuffer : 
       
   100                             iMaxNumOfFrames - iNumOfFramesInSendPacket; 
       
   101 
       
   102     // Some traces for seeing what's going on. 
       
   103     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t Filling sendpacket...")));
       
   104     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t %d frames can fit in packet."), iMaxNumOfFrames));    
       
   105     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t %d frames have already been moved from current buffer to sendpacket."), iNumOfFramesAlreadyMoved));    
       
   106     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t %d frames left to move from current buffer."), numOfFramesLeftInBuffer));    
       
   107     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t %d frames already in current packet."), iNumOfFramesInSendPacket));    
       
   108     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t => Moving %d frames."), numOfFramesToMove));    
       
   109 
       
   110     // Move the number of frames calculated above to the packet: 
       
   111     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t replacing sendpacket content from %d, length is %d..."), KA2DPMediaPacketHeaderLength + iNumOfFramesInSendPacket * iFrameLength, numOfFramesToMove * iFrameLength));    
       
   112 
       
   113     // Make the ptrNextFrameInBuffer point to the first frame that hasn't been moved. 
       
   114     const TUint8 * ptrNextFrameInBuffer = aBuffer.Ptr() + iNumOfFramesAlreadyMoved * iFrameLength; 	
       
   115     memcpy((void *)iPtrEndOfPayload, (void *)ptrNextFrameInBuffer, numOfFramesToMove * iFrameLength); 
       
   116     iPtrEndOfPayload += numOfFramesToMove * iFrameLength; 
       
   117     ptrNextFrameInBuffer += numOfFramesToMove * iFrameLength; 
       
   118 
       
   119     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t %d frames moved from buffer to packet."), numOfFramesToMove));    
       
   120 
       
   121     // If we have now moved them all, reset the counter, otherwise update it for the next round. 
       
   122     iNumOfFramesAlreadyMoved = numOfFramesLeftInBuffer == numOfFramesToMove ? 0 : iNumOfFramesAlreadyMoved + numOfFramesToMove; 
       
   123 
       
   124     // update the information needed for building the header later (in sending phase): 
       
   125     iNumOfFramesInSendPacket += numOfFramesToMove; 
       
   126     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t iNumOfFramesInSendPacket incremented, it is now %d"), iNumOfFramesInSendPacket));    
       
   127 
       
   128     numOfFramesLeftInBuffer -= numOfFramesToMove; 
       
   129 
       
   130     // return the number of frames that will still fit in the packet: 
       
   131     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t returning: %d"), iMaxNumOfFrames - iNumOfFramesInSendPacket - numOfFramesLeftInBuffer));    
       
   132     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::AddBufferToSendPacket() <-")));
       
   133     return (iMaxNumOfFrames - iNumOfFramesInSendPacket - numOfFramesLeftInBuffer); 
       
   134     }
       
   135 
       
   136 // ---------------------------------------------------------------------------
       
   137 // From class CBTAudioStreamSender.
       
   138 // This method stores the frames to the frame buffer and 
       
   139 // when we have enough frames. 
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 TInt CBTAudioStreamSenderSBC::PacketSendingCompleted(TPtr8& aPayloadDesC) 
       
   143     {
       
   144     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::PacketSendingCompleted() ->")));
       
   145     iNumOfFramesInSendPacket = 0; 
       
   146     iPtrEndOfPayload = aPayloadDesC.Ptr() + KA2DPMediaPacketHeaderLength; 
       
   147     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::PacketSendingCompleted() <-")));
       
   148     return KErrNone; 
       
   149     }
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // From class CBTAudioStreamSender.
       
   153 // This method sets up the sender and calculates the required packet  
       
   154 // length according to its own implementation. 
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 TInt CBTAudioStreamSenderSBC::InitSender(RRtpSendPacket& aSendPacket, TPtr8& aPayloadDesC, const TUint aTargetBitrate) 
       
   158     {
       
   159     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::InitSender() ->")));
       
   160     iFrameLength = iNewFrameLength; 
       
   161     iMaxNumOfFrames = iSpaceNeededForBuffer / iFrameLength; 
       
   162 
       
   163     // Make the descriptor point in the beginning of the send packet. 
       
   164     aPayloadDesC.Set(const_cast<TUint8*>(aSendPacket.WritePayload().Ptr()), iSpaceNeededForBuffer, iSpaceNeededForBuffer);
       
   165     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t Descriptor inited, space needed: %d bytes."), iSpaceNeededForBuffer));    
       
   166 
       
   167     iPtrEndOfPayload = aPayloadDesC.Ptr() + KA2DPMediaPacketHeaderLength; 
       
   168 
       
   169     iNumOfFramesInSendPacket = 0; 
       
   170 		
       
   171 		iTimestampOfFirstFrameInSendPacket = 0; 
       
   172 
       
   173 		iDurationOfFrame = CalculateFrameDuration(iFrameLength, aTargetBitrate); 
       
   174     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t iDurationOfFrame: %d"), iDurationOfFrame));    
       
   175 
       
   176     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::InitSender() <-")));
       
   177     return KErrNone; 
       
   178     }
       
   179 
       
   180 TInt CBTAudioStreamSenderSBC::CalculatePacketLength(TUint aOutboundMTUSize, const TUint aFrameLength) 
       
   181     {
       
   182     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CalculatePacketLength() <-")));
       
   183 		if(aFrameLength > 0) // Must not be zero, and cannot be according to A2DP spec. 
       
   184 		    {
       
   185         iNewFrameLength = aFrameLength; 
       
   186 
       
   187 				iSpaceNeededForBuffer = ((aOutboundMTUSize - KA2DPMediaPacketHeaderLength - KRTPHeaderLength) / iNewFrameLength) * iNewFrameLength + KA2DPMediaPacketHeaderLength; 
       
   188 
       
   189     		BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CalculatePacketLength() <-")));
       
   190         return iSpaceNeededForBuffer; 
       
   191         }
       
   192     else 
       
   193         {
       
   194         BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t Length parameter is zero!")));    
       
   195 		    BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CalculatePacketLength() <-")));
       
   196         return 0; 
       
   197         }
       
   198     }
       
   199 
       
   200 TUint CBTAudioStreamSenderSBC::CalculateFrameDuration(const TUint aFrameLength, const TUint aTargetBitrate) 
       
   201     {
       
   202     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CalculateFrameInterval() ->")));
       
   203     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::CalculateFrameInterval() <-")));
       
   204     return static_cast<TUint>(static_cast<TReal>(aFrameLength * 8) / static_cast<TReal>(aTargetBitrate)  * 1000000.0); 
       
   205     }
       
   206 
       
   207 TUint CBTAudioStreamSenderSBC::MaxFramesPerPacket()  
       
   208     {
       
   209     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::FramesPerPacket() ->")));
       
   210     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::FramesPerPacket() <-")));
       
   211     return iMaxNumOfFrames; 
       
   212     }
       
   213 
       
   214 void CBTAudioStreamSenderSBC::AdjustTimestamp(TInt64& aTimestamp) 
       
   215     {
       
   216     BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::AdjustTimestamp() ->")));
       
   217 
       
   218 		// The buffer has been emptied, but there may be space for additional frames in sendpacket. 
       
   219 		// So keep the current timestamp until the sendpacket becomes full. 
       
   220 	  if(iNumOfFramesAlreadyMoved == 0) 
       
   221 			  {
       
   222 		    BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t Buffer became empty.")));
       
   223 				iTimestampChangeFlag = ETrue; 
       
   224 			  }
       
   225 
       
   226 		if(iNumOfFramesInSendPacket == iMaxNumOfFrames) // Adjust the timestamp only when the sendpacket is full. 
       
   227 				{
       
   228 				if(iTimestampChangeFlag != EFalse) 
       
   229 						{
       
   230 						// When the buffer been emptied earlier, take the new timestamp into use and adjust it by the amount of frames we just moved. 
       
   231 						iTimestampOfFirstFrameInSendPacket = aTimestamp + iDurationOfFrame * iNumOfFramesAlreadyMoved; 
       
   232 				    BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t New timestamp %d (low) is in use."), I64LOW(aTimestamp))); 
       
   233 				    BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t New timestamp %d (high) is in use."), I64HIGH(aTimestamp))); 
       
   234 						iTimestampChangeFlag = EFalse; 
       
   235 						}
       
   236 		    BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t Timestamp is %d (low)"), I64LOW(iTimestampOfFirstFrameInSendPacket)));    
       
   237 		    BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FPrint(_L("[BTAudioStreamer]\t Timestamp is %d (high)"), I64HIGH(iTimestampOfFirstFrameInSendPacket)));    
       
   238 
       
   239 				// Use the timestamp first and then do a normal adjustment for the next round. 
       
   240 				aTimestamp = iTimestampOfFirstFrameInSendPacket; 
       
   241 		    iTimestampOfFirstFrameInSendPacket = iTimestampOfFirstFrameInSendPacket + iMaxNumOfFrames * iDurationOfFrame; 
       
   242 				}
       
   243 	  BT_AUDIO_STREAMER_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioStreamer]\t CBTAudioStreamSenderSBC::AdjustTimestamp() <-")));
       
   244     }