multimediacommscontroller/mmccmultiplexer/src/mccmultiplexer.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006 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:   
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <mmf/server/mmfdatabuffer.h>
       
    23 #include "mccmultiplexer.h"
       
    24 #include "mccsinkitem.h"
       
    25 #include "mccinternaldef.h"
       
    26 #include "mccinternalevents.h"
       
    27 #include "mccmultiplexerlogs.h"
       
    28 #include "mccinternalevents.h"
       
    29 #include "mccrtpdatasource.h"
       
    30 
       
    31 // MACROS
       
    32 
       
    33 // LOCAL FUNCTION PROTOTYPES
       
    34 
       
    35 // LOCAL CONSTANTS
       
    36 const TUint KMultiplexerDefBufSize( 160 );
       
    37 
       
    38 // ============================= LOCAL FUNCTIONS ===============================
       
    39         
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CMccMultiplexer::NewL
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 EXPORT_C CMccMultiplexer* CMccMultiplexer::NewL( MDataSource* aSource )
       
    47     {
       
    48 	CMccMultiplexer* self = new ( ELeave ) CMccMultiplexer;
       
    49 	CleanupStack::PushL( self );
       
    50     self->ConstructL( aSource );
       
    51     CleanupStack::Pop( self );
       
    52     return self;
       
    53     }
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CMccMultiplexer::~CMccMultiplexer
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 EXPORT_C CMccMultiplexer::~CMccMultiplexer()
       
    60     {
       
    61     __MULTIPLEXER( "CMccMultiplexer::~CMccMultiplexer" )
       
    62     
       
    63     iSinkItems.ResetAndDestroy();
       
    64     delete iDataBuf;
       
    65     
       
    66     __MULTIPLEXER( "CMccMultiplexer::~CMccMultiplexer, exit" )
       
    67     }
       
    68   
       
    69 // -----------------------------------------------------------------------------
       
    70 // CMccMultiplexer::SourceThreadLogon
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 EXPORT_C TInt CMccMultiplexer::MultiplexerSourceThreadLogon( 
       
    74     MAsyncEventHandler& aEventHandler, 
       
    75     MDataSink& aSink, 
       
    76     TBool aSinkIsDecoder, 
       
    77     TUid aMediaType,
       
    78     TBool aPassAllBuffersSink )
       
    79     {
       
    80     __MULTIPLEXER_INT1( "CMccMultiplexer::MultiplexerSourceThreadLogon, endpoint:",
       
    81                         MCC_ENDPOINT_ID( &aSink ) )
       
    82     
       
    83     TInt err( KErrNone );
       
    84     
       
    85     TRAP( err, 
       
    86           AddSinkL( &aSink, aSinkIsDecoder, aMediaType, aPassAllBuffersSink ) );
       
    87     
       
    88     // Gather events from source and propagate them to all sink owners
       
    89     
       
    90     if ( !err && !iSourceLogonDone )
       
    91         {
       
    92         __MULTIPLEXER( "CMccMultiplexer::MultiplexerSourceThreadLogon, source logon" )
       
    93         
       
    94         err = iSource->SourceThreadLogon( *this );
       
    95         iSourceLogonDone = ETrue;
       
    96         }
       
    97         
       
    98     if ( !err )
       
    99         {
       
   100         err = FindSinkItemIndex( &aSink );
       
   101         if ( err != KErrNotFound )
       
   102             {
       
   103             err = iSinkItems[ err ]->SourceThreadLogon( aEventHandler );
       
   104             }
       
   105         if ( MCC_INTERNAL_ENDPOINT( iSource->DataSourceType().iUid ) )
       
   106             {
       
   107             static_cast<CMccDataSource*>( iSource )->AddUser( &aEventHandler );
       
   108             }
       
   109         }
       
   110         
       
   111     __MULTIPLEXER( "CMccMultiplexer::SourceThreadLogon, exit" )
       
   112     
       
   113     return err;
       
   114     }
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CMccMultiplexer::SourceThreadLogoff
       
   118 // -----------------------------------------------------------------------------
       
   119 //       
       
   120 EXPORT_C TInt CMccMultiplexer::MultiplexerSourceThreadLogoff( MDataSink* aSink )
       
   121     {
       
   122     __MULTIPLEXER_INT1( "CMccMultiplexer::MultiplexerSourceThreadLogoff, endpoint:",
       
   123                         MCC_ENDPOINT_ID( aSink ) )
       
   124     
       
   125     if ( aSink )
       
   126         {
       
   127         TInt index = FindSinkItemIndex( aSink );
       
   128         if ( index != KErrNotFound )
       
   129             {
       
   130             CMccSinkItem* item = iSinkItems[ index ];
       
   131             if ( KMccRtpSourceUid == iSource->DataSourceType() )
       
   132                 {
       
   133                 const RArray<TUint>& payloads = item->RegisteredPayloadTypes();
       
   134                 static_cast<CMccRtpDataSource*>( iSource )
       
   135                     ->UnRegisterPayloadTypes( payloads );
       
   136                 }
       
   137             
       
   138             // Clear current user
       
   139             if ( item == iCurrentUser )
       
   140                 {
       
   141                 iCurrentUser = NULL;
       
   142                 }
       
   143                 
       
   144             TBool passedAllRequests = PassAllRequestsToSource( *item );
       
   145                 
       
   146             iSinkItems.Remove( index );
       
   147 
       
   148             UpdateSinkModes();
       
   149             
       
   150             // Update primary buffer or logoff source
       
   151             HandleCleanup( item, passedAllRequests );
       
   152 
       
   153             return KErrNone;
       
   154             }
       
   155         return KErrNotFound;
       
   156         }
       
   157     return KErrArgument;
       
   158     }
       
   159 
       
   160 // -----------------------------------------------------------------------------
       
   161 // CMccMultiplexer::SetCurrentUserL
       
   162 // -----------------------------------------------------------------------------
       
   163 //    
       
   164 EXPORT_C void CMccMultiplexer::SetCurrentUserL( MDataSink& aSink )
       
   165     {
       
   166     __MULTIPLEXER_INT1( "CMccMultiplexer::SetCurrentUserL, endpoint:", 
       
   167                         MCC_ENDPOINT_ID( &aSink ) )
       
   168     
       
   169     iCurrentUser = FindSinkItemL( &aSink );
       
   170     
       
   171     __MULTIPLEXER( "CMccMultiplexer::SetCurrentUserL, exit" )
       
   172     }
       
   173     
       
   174 // -----------------------------------------------------------------------------
       
   175 // CMccMultiplexer::RegClientForPayloadsL
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 EXPORT_C void CMccMultiplexer::RegClientForPayloadsL( MDataSink& aConsumer, 
       
   179         const RArray<TUint>& aPayloadTypes )
       
   180     {
       
   181     __MULTIPLEXER( "CMccMultiplexer::RegClientForPayloadsL" )
       
   182     __ASSERT_ALWAYS( iSource, User::Leave( KErrNotReady ) );
       
   183     __ASSERT_ALWAYS( KMccRtpSourceUid == iSource->DataSourceType(),
       
   184         User::Leave( KErrNotSupported ) );
       
   185     
       
   186     FindSinkItemL( &aConsumer )->RegisterPayloadTypesL( aPayloadTypes );
       
   187     static_cast<CMccRtpDataSource*>( iSource )
       
   188         ->RegisterPayloadTypesL( aPayloadTypes );
       
   189     }
       
   190     
       
   191 // -----------------------------------------------------------------------------
       
   192 // CMccMultiplexer::Streams
       
   193 // -----------------------------------------------------------------------------
       
   194 //
       
   195 TUint CMccMultiplexer::Streams( TUid /*aMediaType*/ ) const
       
   196     {
       
   197     return 1;
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CMccMultiplexer::FrameTimeInterval
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 TTimeIntervalMicroSeconds CMccMultiplexer::FrameTimeInterval( 
       
   205     TMediaId /*aMediaId*/ ) const
       
   206     {
       
   207     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   208     }  
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CMccMultiplexer::DataSourceType
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 TUid CMccMultiplexer::DataSourceType() const
       
   215     {
       
   216     return KMccMultiplexerUid;
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CMccMultiplexer::FillBufferL
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 void CMccMultiplexer::FillBufferL( 
       
   224     CMMFBuffer* aBuffer, 
       
   225     MDataSink* aConsumer, 
       
   226     TMediaId aMediaId )
       
   227     {
       
   228     __MULTIPLEXER_INT1( "CMccMultiplexer::FillBufferL, endpoint:",
       
   229                         MCC_ENDPOINT_ID( aConsumer ) )
       
   230     __MULTIPLEXER_INT1( "CMccMultiplexer::FillBufferL, mediaId uid:",
       
   231                         aMediaId.iMediaType.iUid )
       
   232     
       
   233     __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
       
   234     __ASSERT_ALWAYS( aBuffer->Type() == KUidMmfDataBuffer, 
       
   235                      User::Leave( KErrArgument ) ); 
       
   236     __ASSERT_ALWAYS( aConsumer, User::Leave( KErrArgument ) );
       
   237     
       
   238     // Store request
       
   239     CMccSinkItem* item = FindSinkItemL( aConsumer );
       
   240     item->FillBufferRequestL( aBuffer );
       
   241                                                         
       
   242     // If not in pass all mode, only one sink at the time can control
       
   243     // the source
       
   244     if ( iState == EPlaying && 
       
   245        ( item->PassAllRequestsToSource() || CanCommandSource( aConsumer ) ) )
       
   246         {
       
   247         __MULTIPLEXER( "CMccMultiplexer::FillBufferL, command source" )
       
   248         
       
   249         if ( KMccRtpSourceUid == iSource->DataSourceType() )
       
   250             {
       
   251             // Multiplexer buffer needed for payload type multiplexing
       
   252             __ASSERT_ALWAYS( 
       
   253                 static_cast<CMMFDataBuffer*>( aBuffer )
       
   254                 ->Data().MaxSize() <= iDataBuf->Data().MaxSize(),
       
   255                 User::Leave( KErrTooBig ) );
       
   256             
       
   257             __MULTIPLEXER( "CMccMultiplexer::FillBufferL, using own buffer" )
       
   258             iDataBuf->SetStatus( EBeingFilled );
       
   259             iDataBuf->SetLastBuffer( EFalse );
       
   260             iSource->FillBufferL( iDataBuf, this, aMediaId );
       
   261             }
       
   262         else
       
   263             {
       
   264             iSource->FillBufferL( aBuffer, this, aMediaId );
       
   265             }
       
   266         }
       
   267         
       
   268     __MULTIPLEXER( "CMccMultiplexer::FillBufferL, exit" )
       
   269     }  
       
   270         
       
   271 // -----------------------------------------------------------------------------
       
   272 // CMccMultiplexer::SourceDataTypeCode
       
   273 // -----------------------------------------------------------------------------
       
   274 //
       
   275 TFourCC CMccMultiplexer::SourceDataTypeCode( 
       
   276 	TMediaId aMediaId )
       
   277     {
       
   278     return iSource->SourceDataTypeCode( aMediaId );
       
   279     }
       
   280 
       
   281 // -----------------------------------------------------------------------------
       
   282 // CMccMultiplexer::SetSourceDataTypeCode
       
   283 // -----------------------------------------------------------------------------
       
   284 //
       
   285 TInt CMccMultiplexer::SetSourceDataTypeCode( 
       
   286     TFourCC aSourceFourCC, 
       
   287     TMediaId aMediaId )
       
   288     {
       
   289     return iSource->SetSourceDataTypeCode( aSourceFourCC, aMediaId );
       
   290     }
       
   291 
       
   292 // -----------------------------------------------------------------------------
       
   293 // CMccMultiplexer::SourceThreadLogon
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 TInt CMccMultiplexer::SourceThreadLogon( 
       
   297     MAsyncEventHandler& /*aEventHandler*/ )
       
   298     {
       
   299     return KErrNotSupported;
       
   300     }
       
   301     
       
   302 // -----------------------------------------------------------------------------
       
   303 // CMccMultiplexer::NegotiateSourceL
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 void CMccMultiplexer::NegotiateSourceL( MDataSink& aDataSink )
       
   307     {
       
   308     __MULTIPLEXER( "CMccMultiplexer::NegotiateSourceL" )
       
   309     
       
   310     if ( !iSourceNegotiationDone )
       
   311         {
       
   312         if ( KUidMmfAudioInput == iSource->DataSourceType() )
       
   313             {
       
   314             // Audio input need settings from real sink.
       
   315             // This is just quick workaround, better way would be to route
       
   316             // those requests through multiplexer to the sink
       
   317             
       
   318             __MULTIPLEXER( "CMccMultiplexer::NegotiateSourceL, negotiate (use sink)" )
       
   319             
       
   320             iSource->NegotiateSourceL( aDataSink );
       
   321             }
       
   322         else
       
   323             {
       
   324             __MULTIPLEXER( "CMccMultiplexer::NegotiateSourceL, negotiate (normal)" )
       
   325             
       
   326             iSource->NegotiateSourceL( *this );
       
   327             }
       
   328             
       
   329         iSourceNegotiationDone = ETrue;
       
   330         }
       
   331     __MULTIPLEXER( "CMccMultiplexer::NegotiateSourceL, exit" )
       
   332     }
       
   333 
       
   334 // -----------------------------------------------------------------------------
       
   335 // CMccMultiplexer::SourceThreadLogoff
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 void CMccMultiplexer::SourceThreadLogoff()
       
   339     {
       
   340     // NOP
       
   341     }
       
   342     
       
   343 // -----------------------------------------------------------------------------
       
   344 // CMccMultiplexer::SourcePrimeL
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 void CMccMultiplexer::SourcePrimeL()
       
   348     {
       
   349     __MULTIPLEXER( "CMccMultiplexer::SourcePrimeL" )
       
   350     
       
   351     if ( SetMultiplexerState( EPrepared ) )
       
   352         {
       
   353         iSource->SourcePrimeL();
       
   354         }
       
   355         
       
   356     __MULTIPLEXER( "CMccMultiplexer::SourcePrimeL, exit" )
       
   357     }
       
   358 
       
   359 // -----------------------------------------------------------------------------
       
   360 // CMccMultiplexer::SourcePlayL
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 void CMccMultiplexer::SourcePlayL()
       
   364     {
       
   365     __MULTIPLEXER( "CMccMultiplexer::SourcePlayL" )
       
   366     
       
   367     if ( SetMultiplexerState( EPlaying ) )
       
   368         {
       
   369         iSource->SourcePlayL();
       
   370         }
       
   371         
       
   372     __MULTIPLEXER( "CMccMultiplexer::SourcePlayL, exit" )
       
   373     }
       
   374 
       
   375 // -----------------------------------------------------------------------------
       
   376 // CMccMultiplexer::SourcePauseL
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 void CMccMultiplexer::SourcePauseL()
       
   380     {
       
   381     __MULTIPLEXER( "CMccMultiplexer::SourcePauseL" )
       
   382     
       
   383     if ( SetMultiplexerState( EResourcePaused ) )
       
   384         {
       
   385         iSource->SourcePauseL();
       
   386         }
       
   387         
       
   388     __MULTIPLEXER( "CMccMultiplexer::SourcePauseL, exit" )
       
   389     }
       
   390 
       
   391 // -----------------------------------------------------------------------------
       
   392 // CMccMultiplexer::SourceStopL
       
   393 // -----------------------------------------------------------------------------
       
   394 //
       
   395 void CMccMultiplexer::SourceStopL()
       
   396     {
       
   397     __MULTIPLEXER( "CMccMultiplexer::SourceStopL" )
       
   398     
       
   399     if ( SetMultiplexerState( EResourceStopped ) )
       
   400         {
       
   401         iSource->SourceStopL();
       
   402         }
       
   403         
       
   404     __MULTIPLEXER( "CMccMultiplexer::SourceStopL, exit" )
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CMccMultiplexer::DataBufferFilledL
       
   409 // -----------------------------------------------------------------------------
       
   410 //
       
   411 void CMccMultiplexer::DataBufferFilledL( 
       
   412     CMMFBuffer* aBuffer, 
       
   413     const TRtpRecvHeader& aRtpHeader )
       
   414     {
       
   415     __MULTIPLEXER( "CMccMultiplexer::DataBufferFilledL" )
       
   416     __ASSERT_ALWAYS( NULL != aBuffer, User::Leave( KErrArgument ) );
       
   417     
       
   418     DoBufferFilledL( aBuffer, &aRtpHeader );
       
   419     }
       
   420 
       
   421 // -----------------------------------------------------------------------------
       
   422 // CMccMultiplexer::ConfigurePayloadFormatL
       
   423 // -----------------------------------------------------------------------------
       
   424 //
       
   425 void CMccMultiplexer::ConfigurePayloadFormatL( const TDesC8& /*aConfigParams*/ )
       
   426     {
       
   427     }
       
   428 
       
   429 // -----------------------------------------------------------------------------
       
   430 // CMccMultiplexer::BufferFilledL
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 void CMccMultiplexer::BufferFilledL( CMMFBuffer* aBuffer )
       
   434 	{
       
   435     __MULTIPLEXER( "CMccMultiplexer::BufferFilledL" )
       
   436     __ASSERT_ALWAYS( NULL != aBuffer, User::Leave( KErrArgument ) );
       
   437     
       
   438     DoBufferFilledL( aBuffer, 0 );
       
   439 	}
       
   440 	
       
   441 // -----------------------------------------------------------------------------
       
   442 // CMccMultiplexer::Duration
       
   443 // -----------------------------------------------------------------------------
       
   444 //
       
   445 TTimeIntervalMicroSeconds CMccMultiplexer::Duration( 
       
   446 	TMediaId /*aMediaType*/ ) const
       
   447     {
       
   448     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   449     }
       
   450 
       
   451 // -----------------------------------------------------------------------------
       
   452 // CMccMultiplexer::CanCreateSourceBuffer
       
   453 // -----------------------------------------------------------------------------
       
   454 //    
       
   455 TBool CMccMultiplexer::CanCreateSourceBuffer()
       
   456     {
       
   457     return ETrue;
       
   458     }
       
   459 
       
   460 // -----------------------------------------------------------------------------
       
   461 // CMccMultiplexer::CreateSourceBufferL
       
   462 // Created buffer is not intended for sink use.
       
   463 // -----------------------------------------------------------------------------
       
   464 //
       
   465 CMMFBuffer* CMccMultiplexer::CreateSourceBufferL( 
       
   466     TMediaId /*aMediaId*/, 
       
   467     TBool& aReference )
       
   468     {
       
   469     __MULTIPLEXER( "CMccMultiplexer::CreateSourceBufferL" )
       
   470     __ASSERT_ALWAYS( iSuggestedBufSize, User::Leave( KErrNotReady ) );
       
   471     
       
   472     aReference = EFalse;
       
   473     
       
   474     if ( iDataBuf->Data().MaxSize() < iSuggestedBufSize )
       
   475         {
       
   476         static_cast<CMMFDescriptorBuffer*>( iDataBuf )
       
   477             ->ReAllocBufferL( iSuggestedBufSize );
       
   478         }
       
   479     
       
   480     CMMFDataBuffer* buf = CMMFDataBuffer::NewL( iSuggestedBufSize );
       
   481     iSuggestedBufSize = 0;
       
   482     return buf;
       
   483     }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // CMccMultiplexer::SuggestSourceBufferSize
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 void CMccMultiplexer::SuggestSourceBufferSize( TUint aSuggestedBufferSize )
       
   490     {
       
   491     __MULTIPLEXER_INT1( "CMccMultiplexer::SuggestSourceBufferSize, SIZE: ",
       
   492          aSuggestedBufferSize )
       
   493     
       
   494     iSuggestedBufSize = aSuggestedBufferSize;
       
   495     }
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 // CMccMultiplexer::SendEventToClient
       
   499 // -----------------------------------------------------------------------------
       
   500 //
       
   501 TInt CMccMultiplexer::SendEventToClient( const TMMFEvent& aEvent )
       
   502     {
       
   503     __MULTIPLEXER( "CMccMultiplexer::SendEventToClient" )
       
   504     
       
   505     // Stream control event has to be stored at this level since control
       
   506     // request can go back to source synchronously causing stream state change
       
   507     // event, which then overwrites the control event.
       
   508     //
       
   509     if ( IS_MCC_EVENT( aEvent ) )
       
   510 	    {
       
   511 	    TMccEvent* mccEventPtr = 
       
   512 	        reinterpret_cast<const TMccInternalEvent&>( aEvent ).iMccEvent;
       
   513 	        
       
   514 	    if ( mccEventPtr && 
       
   515 	         MCC_STREAM_STATE_CHANGE_EVENT( mccEventPtr ) &&
       
   516 	         mccEventPtr->iEventNumData != KMccAutomaticEvent )
       
   517             {
       
   518             if ( iCurrentUser )
       
   519                 {
       
   520                 return iCurrentUser->SendEventToClient( aEvent );
       
   521                 }
       
   522             else
       
   523                 {
       
   524                 __MULTIPLEXER( "CMccMultiplexer::SendEventToClient, KErrNotReady" )
       
   525                 return KErrNotReady;
       
   526                 }
       
   527             }
       
   528         
       
   529 	    if ( mccEventPtr && 
       
   530 	         mccEventPtr->iEventCategory == KMccEventCategoryStreamControl )
       
   531 	        {
       
   532 	        iStreamControlEvent = *mccEventPtr;
       
   533 	        TMccInternalEvent internalEvent( KMccMultiplexerUid, EMccInternalEventNone,
       
   534     		                                 iStreamControlEvent );
       
   535             
       
   536             SendEventToAllClients( internalEvent );
       
   537             
       
   538             return KErrNone;
       
   539 	        }
       
   540 	    }
       
   541 	
       
   542 	SendEventToAllClients( aEvent );        
       
   543 
       
   544     return KErrNone;
       
   545     }
       
   546     
       
   547 // -----------------------------------------------------------------------------
       
   548 // CMccMultiplexer::CMccMultiplexer
       
   549 // -----------------------------------------------------------------------------
       
   550 //
       
   551 CMccMultiplexer::CMccMultiplexer()
       
   552     {
       
   553     }
       
   554 
       
   555 // -----------------------------------------------------------------------------
       
   556 // CMccMultiplexer::ConstructL
       
   557 // -----------------------------------------------------------------------------
       
   558 //
       
   559 void CMccMultiplexer::ConstructL( MDataSource* aSource )
       
   560     {
       
   561     __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
       
   562     
       
   563     iSource = aSource;
       
   564     iDataBuf = CMMFDataBuffer::NewL( KMultiplexerDefBufSize );
       
   565     }
       
   566 
       
   567 // -----------------------------------------------------------------------------
       
   568 // CMccMultiplexer::FindSinkItemL
       
   569 // -----------------------------------------------------------------------------
       
   570 //
       
   571 CMccSinkItem* CMccMultiplexer::FindSinkItemL( MDataSink* aSink )
       
   572     {
       
   573     TInt index = FindSinkItemIndex( aSink );
       
   574     __ASSERT_ALWAYS( index != KErrNotFound, User::Leave( KErrNotFound ) );
       
   575     
       
   576     return iSinkItems[ index ];
       
   577     }
       
   578     
       
   579 // -----------------------------------------------------------------------------
       
   580 // CMccMultiplexer::FindSinkItemIndex
       
   581 // -----------------------------------------------------------------------------
       
   582 //
       
   583 TInt CMccMultiplexer::FindSinkItemIndex( MDataSink* aSink )
       
   584     {
       
   585     for ( TInt i = 0; i < iSinkItems.Count(); i++ )
       
   586         {
       
   587         if ( iSinkItems[ i ]->Match( aSink ) )
       
   588             {
       
   589             return i;
       
   590             }
       
   591         }
       
   592     return KErrNotFound;
       
   593     }
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CMccMultiplexer::CanCommandSource
       
   597 // Primary sink has always preferred access to source, other sinks can use
       
   598 // source only if primary is not using it
       
   599 // -----------------------------------------------------------------------------
       
   600 // 
       
   601 TBool CMccMultiplexer::CanCommandSource( MDataSink* aSink )
       
   602     {
       
   603     TBool canCommandSource( EFalse );
       
   604     if ( IsPrimarySink( aSink ) )
       
   605         {
       
   606         canCommandSource = ETrue;
       
   607         }
       
   608     else if ( iSinkItems.Count() > 0 && 
       
   609               !IsActiveState( iSinkItems[ 0 ]->MultiplexerState() ) )
       
   610         {
       
   611         canCommandSource = ETrue;
       
   612         }
       
   613     else
       
   614         {
       
   615         // NOP
       
   616         }
       
   617     return canCommandSource;
       
   618     }
       
   619     
       
   620 // -----------------------------------------------------------------------------
       
   621 // CMccMultiplexer::IsPrimarySink
       
   622 // -----------------------------------------------------------------------------
       
   623 //    
       
   624 TBool CMccMultiplexer::IsPrimarySink( MDataSink* aSink )
       
   625     {
       
   626     // Primary sink is always the first one
       
   627     return ( iSinkItems.Count() > 0 && iSinkItems[ 0 ]->Match( aSink ) );
       
   628     }
       
   629     
       
   630 // -----------------------------------------------------------------------------
       
   631 // CMccMultiplexer::DoBufferFilledL
       
   632 // -----------------------------------------------------------------------------
       
   633 //
       
   634 void CMccMultiplexer::DoBufferFilledL( 
       
   635     CMMFBuffer* aBuffer, 
       
   636     const TRtpRecvHeader* aRtpHeader )
       
   637     {
       
   638     TUid mediaType = KNullUid;
       
   639     iDataBuf->SetStatus( EFull );
       
   640     
       
   641     if ( iResolveFilledBufferMediaType )
       
   642         {
       
   643         for ( TInt i = 0; i < iSinkItems.Count() && mediaType == KNullUid; i++ )
       
   644             {
       
   645             mediaType = iSinkItems[ i ]->ResolveMediaType( aBuffer );
       
   646             }
       
   647         }
       
   648         
       
   649     for ( TInt i = 0; i < iSinkItems.Count(); i++ )
       
   650         {
       
   651         // First item is always the primary sink, but multiplexer can be
       
   652         // also set into mode where all fillbuffer requests are passed to the
       
   653         // source (i.e. all sinks are kind of primary ones). In such case,
       
   654         // incoming buffer must match the one which was given when fillbuffer
       
   655         // request was issued (i.e. source cannot return different buffer).
       
   656         TBool isPrimary( !i );
       
   657         
       
   658         iSinkItems[ i ]->BufferFilledL( aBuffer, 
       
   659                                         aRtpHeader, 
       
   660                                         isPrimary,
       
   661                                         mediaType );
       
   662         }
       
   663     }   
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CMccMultiplexer::AddSinkL
       
   667 // -----------------------------------------------------------------------------
       
   668 //  
       
   669 void CMccMultiplexer::AddSinkL( 
       
   670     MDataSink* aSink, 
       
   671     TBool aSinkIsDecoder,
       
   672     TUid aMediaType,
       
   673     TBool aPassAllBuffersSink )
       
   674     {
       
   675     __ASSERT_ALWAYS( FindSinkItemIndex( aSink ) == KErrNotFound, 
       
   676                      User::Leave( KErrAlreadyExists ) );
       
   677     
       
   678     CMccSinkItem* item = CMccSinkItem::NewLC( aSink, 
       
   679                                               aSinkIsDecoder, 
       
   680                                               aMediaType, 
       
   681                                               aPassAllBuffersSink );
       
   682     iSinkItems.AppendL( item );
       
   683     CleanupStack::Pop( item );
       
   684     
       
   685     // Update sinks
       
   686     UpdateSinkModes();
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CMccMultiplexer::SetMultiplexerState
       
   691 // -----------------------------------------------------------------------------
       
   692 //    
       
   693 TBool CMccMultiplexer::SetMultiplexerState( TMccMultiplexerState aState )
       
   694     {
       
   695     __MULTIPLEXER_INT1( "CMccMultiplexer::SetMultiplexerState, state:", aState )
       
   696     
       
   697     // If state of the multiplexed source is already what is tried to be set,
       
   698     // multiplexer generates the corresponding completion event
       
   699     TBool controlSource( iState != aState );
       
   700     
       
   701     TMccEventType eventType = KMccEventNone;
       
   702     
       
   703     switch ( aState )
       
   704         {
       
   705         case EPrepared:
       
   706             {
       
   707             eventType = KMccStreamPrepared;
       
   708             
       
   709             if ( iState == EPlaying || iState == EResourcePaused )
       
   710                 {
       
   711                 controlSource = EFalse;
       
   712                 }
       
   713             else
       
   714                 {
       
   715                 iState = aState;
       
   716                 }
       
   717             break;
       
   718             }
       
   719         case EPlaying:
       
   720             {
       
   721             eventType = KMccStreamStarted;
       
   722             iState = aState;
       
   723             break;
       
   724             }
       
   725         case EResourcePaused:
       
   726             {
       
   727             eventType = KMccStreamPaused;
       
   728             iState = aState;
       
   729             break;
       
   730             }
       
   731         case EResourceStopped:
       
   732             {
       
   733             eventType = KMccStreamStopped;
       
   734             iState = aState;
       
   735             break;
       
   736             }
       
   737         default:
       
   738             {
       
   739             break;
       
   740             }
       
   741         }
       
   742     
       
   743     if ( iCurrentUser )
       
   744         {
       
   745         iCurrentUser->SetMultiplexerState( iState );
       
   746         }
       
   747         
       
   748     if ( eventType != KMccEventNone && !controlSource )
       
   749         {
       
   750         SendStreamEventToClient( eventType );
       
   751         }
       
   752         
       
   753     return controlSource;
       
   754     }
       
   755     
       
   756 // -----------------------------------------------------------------------------
       
   757 // CMccMultiplexer::SendStreamEventToClient
       
   758 // -----------------------------------------------------------------------------
       
   759 //     
       
   760 void CMccMultiplexer::SendStreamEventToClient( TMccEventType& aEventType )
       
   761     {
       
   762     __MULTIPLEXER( "CMccMultiplexer::SendStreamEventToClient" )
       
   763     
       
   764    	TMccEvent event( 0, 
       
   765                      0, 
       
   766                      0, 
       
   767                      MCC_ENDPOINT_ID( iSource ), 
       
   768                      KMccEventCategoryStream, 
       
   769                      aEventType, 
       
   770                      KErrNone, 
       
   771                      KNullDesC8 );
       
   772    
       
   773     TMccInternalEvent internalEvent( KMccMultiplexerUid, 
       
   774                                      EMccInternalEventNone,
       
   775                                      event );
       
   776                                      
       
   777     if ( iCurrentUser )
       
   778         {
       
   779         __MULTIPLEXER( "CMccMultiplexer::SendStreamEventToClient, sending to current user" )
       
   780         
       
   781         iCurrentUser->SendEventToClient( internalEvent );
       
   782         }
       
   783     }
       
   784 
       
   785 // -----------------------------------------------------------------------------
       
   786 // CMccMultiplexer::UpdateSinkModes
       
   787 // -----------------------------------------------------------------------------
       
   788 //
       
   789 void CMccMultiplexer::UpdateSinkModes()
       
   790     {
       
   791     __MULTIPLEXER( "CMccMultiplexer::UpdateSinkModes" )
       
   792     
       
   793     // Check if mediatype has to be resolved for each filled buffer
       
   794     iResolveFilledBufferMediaType = EFalse;
       
   795     
       
   796     for ( TInt i = 0; i < iSinkItems.Count(); i++ )
       
   797         {
       
   798         TBool passAllRequestsToSource = PassAllRequestsToSource( *iSinkItems[ i ] );
       
   799         iSinkItems[ i ]->SetSourceMode( passAllRequestsToSource );
       
   800         
       
   801         iResolveFilledBufferMediaType |= passAllRequestsToSource;
       
   802         }
       
   803     
       
   804     __MULTIPLEXER_INT1( "CMccMultiplexer::UpdateSinkModes, resolve buffers mode:", 
       
   805                         iResolveFilledBufferMediaType  )     
       
   806     __MULTIPLEXER( "CMccMultiplexer::UpdateSinkModes, exit" )
       
   807     }
       
   808     
       
   809 // -----------------------------------------------------------------------------
       
   810 // CMccMultiplexer::PassAllRequestsToSource
       
   811 // -----------------------------------------------------------------------------
       
   812 //   
       
   813 TBool CMccMultiplexer::PassAllRequestsToSource( CMccSinkItem& aItem ) const
       
   814     {
       
   815     // If source is filesource, it can support two primary sinks; one for audio
       
   816     // and one for video.
       
   817     //
       
   818 
       
   819     if ( iSource->DataSourceType() == KMccFileSourceUid )
       
   820         {
       
   821         TUid mediaType = aItem.MediaType();
       
   822         for ( TInt i = 0; i < iSinkItems.Count(); i++ )
       
   823             {
       
   824             // If sinkitem has highest preference from group of sinkitems of same
       
   825             // media type, all its requests can be passed to the source
       
   826             if ( mediaType == iSinkItems[ i ]->MediaType() )
       
   827                 {
       
   828                 return ( iSinkItems[ i ] == &aItem );
       
   829                 }
       
   830             }
       
   831         }
       
   832     else if ( iSource->DataSourceType() == KMccRtpSourceUid )
       
   833         {
       
   834         // Payload type multiplexing is used with network resource. Multiple
       
   835         // clients are allowed to request fillbuffer from RTP-source.
       
   836         return ETrue;
       
   837         }
       
   838     else
       
   839         {
       
   840         // Make PC-LINT happy
       
   841         }
       
   842     
       
   843     return EFalse;
       
   844     }
       
   845 
       
   846 // -----------------------------------------------------------------------------
       
   847 // CMccMultiplexer::IsSupportedMediaType
       
   848 // -----------------------------------------------------------------------------
       
   849 //    
       
   850 TBool CMccMultiplexer::IsSupportedMediaType( TUid aMediaType ) const
       
   851     {
       
   852     return ( aMediaType == KUidMediaTypeVideo || 
       
   853              aMediaType == KUidMediaTypeAudio );
       
   854     }
       
   855 
       
   856 // -----------------------------------------------------------------------------
       
   857 // CMccMultiplexer::SendEventToAllClients
       
   858 // -----------------------------------------------------------------------------
       
   859 // 
       
   860 void CMccMultiplexer::SendEventToAllClients( const TMMFEvent& aEvent )
       
   861     {
       
   862     for ( TInt i = 0; i < iSinkItems.Count(); i++ )
       
   863         {
       
   864         iSinkItems[ i ]->SendEventToClient( aEvent );
       
   865         }
       
   866     }
       
   867 
       
   868 // -----------------------------------------------------------------------------
       
   869 // CMccMultiplexer::HandleCleanup
       
   870 // -----------------------------------------------------------------------------
       
   871 //
       
   872 void CMccMultiplexer::HandleCleanup( 
       
   873     CMccSinkItem* aSinkItem, 
       
   874     TBool aPassedAllRequests )
       
   875     {
       
   876     TRAP_IGNORE( HandleCleanupL( aSinkItem, aPassedAllRequests ) )
       
   877     delete aSinkItem;
       
   878     }
       
   879     
       
   880 // -----------------------------------------------------------------------------
       
   881 // CMccMultiplexer::HandleCleanupL
       
   882 // -----------------------------------------------------------------------------
       
   883 //
       
   884 void CMccMultiplexer::HandleCleanupL( 
       
   885     CMccSinkItem* aSinkItem,
       
   886     TBool aPassedAllRequests )
       
   887     {
       
   888     __MULTIPLEXER( "CMccMultiplexer::HandleCleanupL" )
       
   889     
       
   890      if ( iSinkItems.Count() == 0 )
       
   891         {
       
   892         // If no more sinks, source can be logged off
       
   893         iSource->SourceThreadLogoff();
       
   894         iSourceLogonDone = EFalse;
       
   895         }
       
   896      else
       
   897         {      
       
   898         // Update source's sinkbuffer (may be also NULL) and user info
       
   899         
       
   900         if ( aSinkItem )
       
   901             {
       
   902             if ( aPassedAllRequests )
       
   903                 {
       
   904                 __MULTIPLEXER( "CMccMultiplexer::HandleCleanupL, clear old" )
       
   905                 iSource->FillBufferL( NULL, this, TMediaId( aSinkItem->MediaType() ) );
       
   906                 }
       
   907             
       
   908             if ( MCC_INTERNAL_ENDPOINT( iSource->DataSourceType().iUid ) )
       
   909                 {
       
   910                 static_cast<CMccDataSource*>( 
       
   911                     iSource )->RemoveUser( aSinkItem->EventHandler() );
       
   912                 }
       
   913             }
       
   914             
       
   915         CMMFBuffer* newPrimaryBuf = iSinkItems[ 0 ]->RequestedBuffer();
       
   916         
       
   917         if ( newPrimaryBuf && KMccRtpSourceUid == iSource->DataSourceType() )
       
   918             {
       
   919             // When payload type multiplexing, multiplexer's own buffer is used
       
   920             newPrimaryBuf = iDataBuf;
       
   921             }
       
   922         
       
   923         __MULTIPLEXER( "CMccMultiplexer::HandleCleanupL, set new" )    
       
   924         iSource->FillBufferL( newPrimaryBuf, 
       
   925                               this, 
       
   926                               TMediaId( iSinkItems[ 0 ]->MediaType() ) );
       
   927         }
       
   928     
       
   929     __MULTIPLEXER( "CMccMultiplexer::HandleCleanupL, exit" )
       
   930     }
       
   931     
       
   932 // -----------------------------------------------------------------------------
       
   933 // CMccMultiplexer::IsActiveState
       
   934 // -----------------------------------------------------------------------------
       
   935 //
       
   936 TBool CMccMultiplexer::IsActiveState( TMccMultiplexerState aState ) const
       
   937     {
       
   938     return ( aState == EPlaying );
       
   939     }
       
   940     
       
   941 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // E32Dll.
       
   945 // DLL Entry point
       
   946 // Returns: KErrNone
       
   947 // -----------------------------------------------------------------------------
       
   948 //
       
   949 #ifndef EKA2
       
   950 EXPORT_C TInt E32Dll( TDllReason )
       
   951     {
       
   952     return KErrNone;
       
   953     }
       
   954 #endif
       
   955 
       
   956 
       
   957 //  End of File 
       
   958