bluetoothengine/btaudiostreamer/inc/btaudiostreamsender.h
changeset 0 f63038272f30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btaudiostreamer/inc/btaudiostreamsender.h	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,350 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  This class implements the audio data sending behaviour 
+*                that is common to all codecs. 
+*
+*/
+
+
+
+#ifndef __BTAUDIOSTREAMSENDER_H__
+#define __BTAUDIOSTREAMSENDER_H__
+
+#include <bluetooth/a2dpoptimisation.h>
+#include <bluetooth/a2dpoptimisationparams.h>
+ 
+#include "btaudiostreamer.h" 
+
+/**
+ *  This class handles the sending of RTP frames on general level. 
+ *
+ *  This class takes care of all the operations related to an RTP frame that are 
+ *  common to all formats. Such operations are e.g. timestamp handling and 
+ *  frame sending. 
+ *  
+ *  The child classes of this are used for handling the encoder specific 
+ *  frame handling. This class specifies and calls pure virtual methods that 
+ *  must be implemented by an encoder specific child class. 
+ *
+ *  @lib btaudiostreamer.lib
+ *  @since S60 v3.1 
+ */
+NONSHARABLE_CLASS(CBTAudioStreamSender) : public CActive
+    {
+    public:
+    static CBTAudioStreamSender* NewL(MBTAudioStreamSenderObserver& aObserver, RRtpSession& aSession);
+    ~CBTAudioStreamSender();
+
+    /**
+     * A callback for registering with RTP API 
+     *
+     * @since S60 v3.1
+     * @param aPtr  An pointer to an instance that handles the callback. 
+     * @param aEvent Handle to the event that occurred. 
+     * @return void. 
+     */
+    static void PacketSent(CBTAudioStreamSender* aPtr, const TRtpEvent& aEvent);
+    /**
+     * A callback for registering with RTP API 
+     *
+     * @since S60 v3.1
+     * @param aPtr  An instance who handles the callback. 
+     * @param aEvent Handle to the event that occurred. 
+     * @return void. 
+     */
+    static void SendError(CBTAudioStreamSender* aPtr, const TRtpEvent& aEvent);
+
+    /**
+     * Method for actually handling the RTP API callbacks for sent packets. 
+     *
+     * @since S60 v3.1
+     * @return void. 
+     */
+    virtual void DoPacketSent();
+
+    /**
+     * Method for actually handling the RTP API callback for send errors. 
+     *
+     * @since S60 v3.1
+     * @return void. 
+     */
+    virtual void DoSendError();
+
+    virtual TInt SetNewFrameLength(TUint aOutboundMTUSize, const TUint aFrameLength, const TUint aTargetBitrate);
+
+    /**
+     * This method prepares the Stream Sender for incoming audio buffers. 
+     *
+     * @since S60 v3.1
+     * @param aOutboundMTUSize The MTU size for outgoing L2CAP link. 
+     * @param aFrameLength  The length of one audio data frame. 
+     * @return void. 
+     */
+    virtual void StartL(TUint aOutboundMTUSize, const TUint aFrameLength, const TUint aTargetBitrate);
+
+    /**
+     * This method contains the code for closing the RTP API and cleaning up. 
+     *
+     * @since S60 v3.1
+     * @return void. 
+     */
+    virtual void Stop();
+
+    /**
+     * An implementation of the buffer handling method. 
+     *
+     * @since S60 v3.1
+     * @param aBuffer contains the audio data frames. 
+     * @param aTimestamp The timestamp of the audio data frames. 
+     * @return a Symbian OS wide error code. 
+     */
+    virtual TInt SendThisBuffer(const TDesC8& aBuffer, TTimeIntervalMicroSeconds aTimestamp);
+
+    protected: 
+    void ConstructL();
+    CBTAudioStreamSender(MBTAudioStreamSenderObserver& aObserver, RRtpSession& aSession);
+
+    void RunL();
+    void DoCancel();
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method moves the audio frames from buffer to SendPacket in encoder specific way. 
+     *
+     * @since S60 v3.1
+     * @param aBuffer contains the audio data frames. 
+     * @return a Symbian OS wide error code. 
+     */
+    virtual TInt AddBufferToSendPacket(const TDesC8& aBuffer) = 0; 
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method places a header to SendPacket in encoder specific way. 
+     *
+     * @since S60 v3.1
+     * @param void. 
+     * @return a Symbian OS wide error code. 
+     */
+    virtual TInt AddHeaderToSendPacket(TPtr8& aPayloadDesC) = 0; 
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method handles the encoder specific operations that should be done after the packet 
+     * has been sent. 
+     *
+     * @since S60 v3.1
+     * @param void. 
+     * @return a Symbian OS wide error code. 
+     */
+    virtual TInt PacketSendingCompleted(TPtr8& aPayloadDesC) = 0; 
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method handles the encoder specific packet length calculation.  
+     *
+     * @since S60 v3.1
+     * @param aOutboundMTUSize The MTU size for outgoing L2CAP link. 
+     * @param aFrameLength  The length of one audio data frame. 
+     * @return a Symbian OS wide error code. 
+     */
+    virtual TInt CalculatePacketLength(TUint aOutboundMTUSize, const TUint aFrameLength) = 0; 
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method returns the maximum number of frames in one outgoing packet.  
+     *
+     * @since S60 Timebox 9.2
+     * @return number of frames in one send packet. 
+     */
+    virtual TUint MaxFramesPerPacket() = 0; 
+
+    /**
+     * 
+     * This method calculates the playing time of one frame in microseconds.
+     * The result is encoder specific. 
+     *
+     * @since S60 Timebox 9.2
+     * @param void. 
+     * @return a duration of one frame. 
+     */
+    virtual TUint CalculateFrameDuration(const TUint aFrameLength, const TUint aTargetBitrate) = 0; 
+
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method handles the encoder specific initialisation.  
+     *
+     * @since S60 v3.1
+     * @param void. 
+     * @return void. 
+     */
+    virtual TInt InitSender(RRtpSendPacket& aSendPacket, TPtr8& aPayloadDesC, const TUint aTargetBitrate) = 0; 
+
+    /**
+     * A pure virtual method that must be implemented by the encoder specific child class. 
+     * This method adjusts the incoming timestamp if buffers don't fill the SendPacket exactly.  
+     *
+     * @since S60 v5.0
+     * @param aTimestamp A 64 bit representation of the timestamp to adjust. This will change during the call. 
+     * @return void. 
+     */
+	virtual void AdjustTimestamp(TInt64 &aTimestamp) = 0; 
+
+
+    private: 
+    /**
+     * An inline method that empties the received buffer. 
+     * This method uses encoder specific inherited class to handles the encoder specific data.  
+     * and then decides whether to send the data out or request for more data. 
+     *
+     * @since S60 v3.1
+     * @param void. 
+     * @return void. 
+     */
+    inline void ConsumeBuffer(); 
+
+    /**
+     * An inline method that switches to new sendpacket when the length of frame has changed. 
+     * This method also initializes the sender to use the new packet. 
+     *
+     * @since S60 v3.1
+     * @param void. 
+     * @return void. 
+     */
+		inline void SwitchToNewSendPacket(); 
+
+    /**
+     * An inline method that self completes this active object. 
+     * The purpose of this is to set the data provider thread free 
+     * and continue execution in this thread's context.  
+     *
+     * @since S60 v3.1
+     * @param void. 
+     * @return void. 
+     */
+    inline void ProceedToPacketSending(); 
+
+    
+    private: 
+
+    /**
+     * The possible states of the Streamer. 
+     */
+    enum TStreamerState
+        {
+        EStopped, 
+        EBuffering,
+        ESending, 
+        EErrorSending 
+        };
+
+    /**
+    * A2DP optimiser object that is needed for prioritising A2DP audio over other data. 
+    */
+   RA2dpOptimiser iA2DPOptimiser; 
+
+   /**
+    * This stores a reference to the observer of this class. 
+    */
+   MBTAudioStreamSenderObserver&    iObserver;
+
+   /**
+    * RTP session reference, needed for creating the SendSource. 
+    */
+   RRtpSession&    iRtpSession;
+
+   /**
+    * RRtpSendSoure is needed for SendPacket management. 
+    */
+   RRtpSendSource    iSendSrc;
+
+   /**
+    * This stores the timestamp which we must place in the header. 
+    */
+   TInt64 iTimestamp; 
+
+    /**
+     * This stores the timestamp which we must place in the header. 
+     */
+    TInt64 iAdjustedTimestamp; 
+
+
+   /**
+    * This stores the current state of the streamer. 
+    */
+   TStreamerState     iStreamerState; 
+
+   /**
+    * This stores a reference to the buffer until it has 
+    * been emptied and can be given back to the audio adaptation. 
+    */
+   const TDesC8 *iBuffer; 
+
+   /**
+    * These assist with creating RTP payloads with proper header and content. 
+    */
+   RRtpSendPacket*   iCurrentSendPacket; 
+   RRtpSendPacket*   iSpareSendPacket; 
+   
+   /**
+    * A pointer to the send packet's contents. 
+    * It is used to abstract away the container of the data. 
+    */
+    TPtr8            iPayloadDesC;
+
+   /**
+    * An instance of our thread. This is needed for self completing 
+    * the requests, which forces the ActiveScheduler to call our RunL. 
+    */
+   RThread iThread; 
+
+    /**
+     * This stores the new framelength when the streaming parameters are changing. 
+     */
+    TInt iNewFrameLength; 
+
+    /**
+     * This stores the target bitrate. The reason for this is that it is not applied 
+     * immediately, but after the current packet is sent. 
+     */
+    TUint iTargetBitrate; 
+
+    /**
+     * This tells if the frame length is changing. If it is, then we won't put 
+     * frames of new length into the same packet with the old frames. 
+     * After sending the old frames a new sendpacket is taken into use.   
+     */
+    TBool iChangingFrameLength; 
+		
+    /**
+     * This tells whether we should keep the previous timestamp or overwrite 
+     * it with the most recent one. 
+     */
+    TBool     iKeepPreviousTimestamp; 
+
+    /**
+     * This tells whether we should keep moving data from buffer to an incoming frame. 
+     * The value is set to ETrue when new frame arrives and when the buffer was completely consumed 
+     * and sent, this value is set to EFalse. 
+     */
+    TBool     iNonprocessedDataInBuffer; 
+
+    /**
+     * This tells if the streaming optimiser service is available. 
+     */
+    TBool     iLinkOptimiserAvailable; 
+
+    };
+
+#endif // __BTAUDIOSTREAMSENDER_H__