multimediacommscontroller/mmccredpayloadformat/src/mccredpayloadwrite.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccredpayloadformat/src/mccredpayloadwrite.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,386 @@
+/*
+* Copyright (c) 2005-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:    Implements format encode interface for redundancy plugin.
+*
+*/
+
+
+
+
+
+// INCLUDE FILES
+#include "rtpheader.h"
+#include "mccredpayloadwrite.h"
+#include "mccredencoder.h"
+#include "mccrtpdatasink.h"
+#include "mccredpayloadformatdefs.h"
+#include "mccdef.h"
+#include "mccinternaldef.h"
+#include "mccrtpmediaclock.h"
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::CMccRedPayloadWrite
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMccRedPayloadWrite::CMccRedPayloadWrite()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::ConstructL( MDataSink* aSink )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::ConstructL" )
+    __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
+    
+    iClip = aSink;
+    iRedEncoder = CMccRedEncoder::NewL();
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMccRedPayloadWrite* CMccRedPayloadWrite::NewL( MDataSink* aSink )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::NewL" )
+    __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( KMccRtpSinkUid == aSink->DataSinkType(),
+        User::Leave( KErrNotSupported ) );
+    
+    CMccRedPayloadWrite* self = new( ELeave ) CMccRedPayloadWrite;
+    
+    CleanupStack::PushL( self );
+    self->ConstructL( aSink );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+    
+// Destructor
+CMccRedPayloadWrite::~CMccRedPayloadWrite()
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::~CMccRedPayloadWrite" )
+        
+    delete iRedEncoder;
+    delete iSinkBuffer;
+    iDataSource = NULL;
+    iBufToEmptyPtr = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadRead::ConfigurePayloadFormatL
+// Configure payload encoding parameters.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::ConfigurePayloadFormatL( const TDesC8& aConfigParams,
+        CMccRtpMediaClock& /*aClock*/ )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::ConfigurePayloadFormatL" )
+    __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccRedPayloadWriteConfig ),
+        User::Leave( KErrArgument ) );
+    
+    TMccRedPayloadWritePckg cPckg;
+    cPckg.Copy( aConfigParams );
+    iPLConfig = cPckg();
+
+    __ASSERT_ALWAYS( iPLConfig.iRedBlockCount <= KMaxRedCount, 
+        User::Leave( KErrArgument ) );
+    
+    if ( iSinkBuffer )
+        {
+        delete iSinkBuffer;
+        iSinkBuffer = NULL;
+        }
+    
+    // Extra variables for clarity
+    TInt redPayloadSize
+        = iPLConfig.iMaxPayloadSize * ( 1 + iPLConfig.iRedBlockCount );
+    TInt redHeadersSize 
+        = iPLConfig.iRedBlockCount * KRedHeaderSize + KFinalHeaderSize;
+    iSinkBuffer = CMMFDataBuffer::NewL( redPayloadSize + redHeadersSize );
+                                    
+    iRedEncoder->InitializeL( iPLConfig.iRedBlockCount,
+                              iPLConfig.iMaxPayloadSize, 
+                              iPLConfig.iNumOfEncodings );
+                              
+    RArray<TUint> encPTs;
+    CleanupClosePushL( encPTs );
+
+    TInt maxNumOfEncodings = iPLConfig.iEncPayloadTypes.Count();
+    for ( TInt i = 0; i < maxNumOfEncodings; i++ )
+        {
+        if ( KPayloadNotDefined != iPLConfig.iEncPayloadTypes[i] )
+            {
+            encPTs.AppendL( iPLConfig.iEncPayloadTypes[i] );
+            }
+        }
+
+    User::LeaveIfError( iRedEncoder->SetPayloadTypes( encPTs ) );
+    CleanupStack::PopAndDestroy( &encPTs );
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::FrameTimeInterval
+// NOT USED. Pure virtual method implementation from CMMFormatEncode needed.
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccRedPayloadWrite::FrameTimeInterval( 
+        TMediaId /*aMediaType*/ ) const
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::FrameTimeInterval" )
+
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::Duration
+// NOT USED. Pure virtual method implementation from CMMFormatEncode needed.
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccRedPayloadWrite::Duration( 
+        TMediaId /*aMediaType*/ ) const
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::Duration" )
+
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::CreateSinkBufferL
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CMccRedPayloadWrite::CreateSinkBufferL( TMediaId /*aMediaId*/,
+                                                    TBool& /*aReference*/ )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::CreateSinkBufferL" )
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::DataSinkType
+//
+// -----------------------------------------------------------------------------
+//
+TUid CMccRedPayloadWrite::DataSinkType() const
+    {
+    return TUid::Uid( KImplUidRedPayloadFormatEncode );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkDataTypeCode
+// NOT USED.
+// -----------------------------------------------------------------------------
+//
+TFourCC CMccRedPayloadWrite::SinkDataTypeCode( TMediaId /*aMediaId*/ )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkDataTypeCode" )
+        
+    return TFourCC();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SetSinkDataTypeCode
+// NOT USED.
+// -----------------------------------------------------------------------------
+//
+TInt CMccRedPayloadWrite::SetSinkDataTypeCode( TFourCC /*aSinkFourCC*/,
+                                               TMediaId /*aMediaId*/ )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SetSinkDataTypeCode" )
+        
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkThreadLogon
+// Passes state transition to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+TInt CMccRedPayloadWrite::SinkThreadLogon( MAsyncEventHandler& aEventHandler )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkThreadLogon" )
+        
+    iClip->SinkThreadLogon( aEventHandler );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkThreadLogoff
+// Passes state transition to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::SinkThreadLogoff()
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkThreadLogoff" )
+        
+    iClip->SinkThreadLogoff();    
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkPrimeL
+// Passes state transition to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::SinkPrimeL()
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkPrimeL" )
+        
+    iClip->SinkPrimeL();
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkPlayL
+// Passes state transition to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::SinkPlayL()
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkPlayL" )
+        
+    iClip->SinkPlayL();
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkPauseL
+// Passes state transition to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::SinkPauseL()
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkPauseL" )
+        
+    iClip->SinkPauseL();
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SinkStopL
+// Passes state transition to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::SinkStopL()
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SinkStopL" )
+        
+    iClip->SinkStopL();
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::EmptyBufferL
+// NOT USED.
+// Overloaded emptybuffer with additional RTP header parameter used instead.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::EmptyBufferL( CMMFBuffer* /*aBuffer*/,
+                                        MDataSource* /*aSupplier*/, 
+                                        TMediaId /*aMediaId*/ )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL" )
+        
+    User::Leave( KErrNotSupported );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::BufferEmptiedL
+// Called by data sink of redundancy payload plugin, when payload is emptied.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::BufferEmptiedL( CMMFBuffer* aBuffer )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::BufferEmptiedL" )
+    __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iBufToEmptyPtr, User::Leave( KErrNotReady ) );
+    
+    iDataSource->BufferEmptiedL( iBufToEmptyPtr );
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::EmptyBufferL
+// Encodes contents of source buffer with redundancy encoder and forwards
+// result buffer to the data sink of redundancy payload plugin.
+// -----------------------------------------------------------------------------
+//
+void CMccRedPayloadWrite::EmptyBufferL( CMMFBuffer* aSourceBuffer,
+                                        MDataSource* aSupplier, 
+                                        TMediaId aMediaId,
+                                        TRtpSendHeader& aSendHeader )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL" )
+    __ASSERT_ALWAYS( aSourceBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( KUidMmfDataBuffer == aSourceBuffer->Type(),
+        User::Leave( KErrNotSupported ) );
+    __ASSERT_ALWAYS( aSupplier, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( KUidMediaTypeAudio == aMediaId.iMediaType,
+        User::Leave( KErrNotSupported ) );
+    
+    DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL() - MEDIA TYPE OK" )
+    
+    iDataSource = aSupplier;
+    iBufToEmptyPtr = static_cast<CMMFDataBuffer*>( aSourceBuffer );
+
+    if ( KComfortNoisePT != aSendHeader.iPayloadType )
+        {
+        // Comfort noise packets are forwarded without encoding
+        iRedEncoder->SetEncodingBlockL( 
+            EMccPrimaryEncoding, iBufToEmptyPtr->Data() );
+        iRedEncoder->EncodePayloadL( aSendHeader.iTimestamp );
+        iRedEncoder->GetEncodingBlockL( EMccRTPPayload, iSinkBuffer->Data() );
+
+        DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL() - Buffer encoded" )
+        aSendHeader.iPayloadType = iPLConfig.iRedPayloadType;
+        }
+
+    // Deliver the packet
+    static_cast<CMccRtpDataSink*>( iClip )
+        ->EmptyBufferL( iSinkBuffer, this, aMediaId, aSendHeader );
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccRedPayloadWrite::SetPayloadTypes
+// Set payload types to accept as encodings.
+// -----------------------------------------------------------------------------
+//
+TInt CMccRedPayloadWrite::SetPayloadTypes( RArray<TUint>& aPayloadTypes )
+    {
+    DP_RED_ENCODE( "CMccRedPayloadWrite::SetPayloadTypes" )
+        
+    if ( aPayloadTypes.Count() )
+        {
+        iPLConfig.iRedPayloadType = aPayloadTypes[0];
+        aPayloadTypes.Remove( 0 );
+        
+        return iRedEncoder->SetPayloadTypes( aPayloadTypes );
+        }
+    else
+        {
+        return KErrArgument;
+        }        
+    }
+    
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File