multimediacommscontroller/mmccfilesourcesink/src/mccfilesourceimpl.cpp
changeset 0 1bce908db942
child 18 91f50911ea81
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 <es_sock.h>
       
    23 #include <e32std.h>
       
    24 #include "mccfilesourceimpl.h"
       
    25 #include "mmcccodecinformation.h"
       
    26 #include "mccfilesourcelogs.h"
       
    27 #include "mccfileaudio.h"
       
    28 #include "mccfilevideo.h"
       
    29 #include "mccinternalevents.h"
       
    30 #include "mmccinterfacedef.h"
       
    31 
       
    32 
       
    33 
       
    34 // ============================ MEMBER FUNCTIONS ===============================
       
    35 
       
    36 // -----------------------------------------------------------------------------
       
    37 // CMccFileSourceImpl::NewL
       
    38 // Static constructor.
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 CMccFileSourceImpl* CMccFileSourceImpl::NewL( 
       
    42     TUint32 aEndpointId, 
       
    43     MMccResources* aMccResources )
       
    44     {
       
    45     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::NewL" )
       
    46     
       
    47     CMccFileSourceImpl* self = new ( ELeave ) CMccFileSourceImpl( aEndpointId );
       
    48     CleanupStack::PushL(self);
       
    49     self->ConstructL( aMccResources );
       
    50     CleanupStack::Pop(self);
       
    51     return self;
       
    52     }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CMccFileSourceImpl::ConstructL
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 void CMccFileSourceImpl::ConstructL( MMccResources* aMccResources )
       
    59     {
       
    60     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::ConstructL" )
       
    61     
       
    62     iFileAudio = CMccFileAudio::NewL( *this );
       
    63     iFileVideo = CMccFileVideo::NewL( *this, aMccResources, iEndpointId );
       
    64     }
       
    65     
       
    66 // -----------------------------------------------------------------------------
       
    67 // Destructor.
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 CMccFileSourceImpl::CMccFileSourceImpl( TUint32 aEndpointId )
       
    71 	: iCurrentState( EConstructed ),
       
    72 	  iIsAudio ( EFalse ),
       
    73 	  iIsVideo ( EFalse ),
       
    74 	  iEndpointId( aEndpointId ),
       
    75 	  iDelayAfterStop( 0 ),
       
    76 	  iEofTimer( 0 )
       
    77     {
       
    78     }
       
    79         
       
    80 // -----------------------------------------------------------------------------
       
    81 // CMccFileSourceImpl::~CMccFileSourceImpl.
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 CMccFileSourceImpl::~CMccFileSourceImpl()
       
    85     {
       
    86     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::~CMccFileSourceImpl" )
       
    87  
       
    88     StopEofTimer();
       
    89 
       
    90     if ( iMP4Handle )
       
    91 	    {
       
    92         MP4ParseClose( iMP4Handle );
       
    93 	    iMP4Handle = NULL;
       
    94 	    }
       
    95 
       
    96     delete iFileAudio;
       
    97 	delete iFileVideo;  
       
    98 
       
    99 	iAsyncEventHandler = NULL;
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CMccFileSourceImpl::AddDataSink(MCMRMediaSink* aSink)
       
   104 //
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 void CMccFileSourceImpl::AddDataSink( MCMRMediaSink* /*aSink*/ )
       
   108     {
       
   109     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AddDataSink" )
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CMccFileSourceImpl::OpenFileL(TFileName aFileName)
       
   114 //
       
   115 // Opens a 3gp file for streaming and reads media descriptions into
       
   116 // member variables
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 void CMccFileSourceImpl::OpenFileL( TFileName aFileName, TBool aFileChangeMode )
       
   120     {
       
   121     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileL" )
       
   122     
       
   123     TCurrentState oldState = iCurrentState;
       
   124     
       
   125     // Close old file (if exists)
       
   126     CloseFileL( aFileChangeMode );
       
   127   
       
   128     aFileName.ZeroTerminate();
       
   129 
       
   130     TRAPD( err, OpenFileForStreamingL( aFileName ) );
       
   131     if ( err )
       
   132         {
       
   133         if ( aFileChangeMode )
       
   134             {
       
   135             // Have to stop timers etc, since old file was closed
       
   136             // and the new file is unusable
       
   137             DoCleanupL( EFalse );
       
   138             }
       
   139         User::Leave( err );
       
   140         }
       
   141 		
       
   142 	this->SetFileName( aFileName );
       
   143 	
       
   144 	if ( oldState == EPlaying )
       
   145 	    {
       
   146 	    // Continue playing with new file
       
   147 	    iCurrentState = EPrimed;
       
   148 	    SourcePlayL( ETrue, aFileChangeMode );
       
   149 	    }
       
   150 	else
       
   151 	    {
       
   152 	    // Keep old state
       
   153 	    iCurrentState = oldState;
       
   154 	    }
       
   155 
       
   156     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFile, exit" )
       
   157     }
       
   158 
       
   159 // -----------------------------------------------------------------------------
       
   160 // CMccFileSourceImpl::CloseFileL()
       
   161 //
       
   162 // Closes the 3gp file
       
   163 // -----------------------------------------------------------------------------
       
   164 //
       
   165 void CMccFileSourceImpl::CloseFileL( TBool aFileChangeMode )
       
   166     {
       
   167     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::CloseFileL" )
       
   168     
       
   169     if ( iCurrentState == EPlaying )
       
   170         {
       
   171         SourceStopL( ETrue, aFileChangeMode );
       
   172         }
       
   173     
       
   174     if ( iMP4Handle ) 
       
   175 	    {
       
   176 	    if ( MP4ParseClose( iMP4Handle ) != MP4_OK )
       
   177 	        {
       
   178 	        User::Leave( KErrGeneral );
       
   179 	        }
       
   180     	iMP4Handle = NULL;
       
   181     	iFileAudio->SetFileHandle( iMP4Handle );
       
   182 	    iFileVideo->SetFileHandle( iMP4Handle );		
       
   183 	    }
       
   184     
       
   185     iCurrentState = EConstructed;
       
   186     
       
   187     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::CloseFileL, file closed" )
       
   188     }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CMccFileSourceImpl::FileNameL()
       
   192 // -----------------------------------------------------------------------------
       
   193 //   
       
   194 TFileName& CMccFileSourceImpl::FileNameL()
       
   195     {
       
   196     return iFileName;
       
   197     }
       
   198 
       
   199 // -----------------------------------------------------------------------------
       
   200 // CMccFileSourceImpl::SetPositionL(TTimeIntervalMicroSeconds aPosition)
       
   201 // 
       
   202 // Sets a new streaming position
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 void CMccFileSourceImpl::SetPositionL( TTimeIntervalMicroSeconds aPosition )
       
   206     {
       
   207     __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::SetPositionL (us):", 
       
   208                                 aPosition.Int64() )
       
   209  	
       
   210  	if ( iCurrentState == EStopped ) 
       
   211     	{
       
   212     	return;
       
   213     	}
       
   214 
       
   215     TUint32 position = MicroToMilliSeconds( aPosition );
       
   216     
       
   217     if ( VideoInUse() ) 
       
   218 	    {
       
   219 	    iFileVideo->SetPositionL( position );
       
   220 	    
       
   221 	    // Position might not end up to what was requested as it is set to
       
   222 	    // nearest IFrame.  With audio there's no such limitation and
       
   223 	    // therefore it is good to use actual video position for audio.
       
   224 	    position = iFileVideo->Position();
       
   225 	    
       
   226 	    __FILESOURCE_CONTROLL_INT1( "Pos modified to nearest IFrame (ms):", 
       
   227                                     position )
       
   228 	    }
       
   229 	    
       
   230 	if ( AudioInUse() )
       
   231 		{
       
   232 		iFileAudio->SetPositionL( position );	
       
   233 		}
       
   234 	}
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // CMccFileSourceImpl::VideoTypeL()
       
   238 // 
       
   239 // Returns current video type
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 CCMRMediaBuffer::TBufferType CMccFileSourceImpl::VideoTypeL()
       
   243     {
       
   244     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoTypeL" )
       
   245 
       
   246     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   247     
       
   248     return iFileVideo->Type();
       
   249     }
       
   250 
       
   251 // -----------------------------------------------------------------------------
       
   252 // CMccFileSourceImpl::AudioTypeL()
       
   253 // 
       
   254 // Returns current audio type
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 CCMRMediaBuffer::TBufferType CMccFileSourceImpl::AudioTypeL()
       
   258     {
       
   259     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioTypeL" )
       
   260 
       
   261     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   262 
       
   263     return iFileAudio->Type();
       
   264     }
       
   265     
       
   266 // -----------------------------------------------------------------------------
       
   267 // CMccFileSourceImpl::VideoFrameRateL()
       
   268 // 
       
   269 // Returns current video frame rate
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 TReal CMccFileSourceImpl::VideoFrameRateL()
       
   273     {
       
   274     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFrameRateL" )
       
   275 
       
   276     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   277         
       
   278     return iFileVideo->VideoFrameRateL();    
       
   279     }
       
   280 
       
   281 // -----------------------------------------------------------------------------
       
   282 // CMccFileSourceImpl::AudioBitRateL()
       
   283 // 
       
   284 // Returns current audio bit rate
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 TUint32 CMccFileSourceImpl::AudioBitRateL()
       
   288     {
       
   289     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioBitRateL" )
       
   290     
       
   291     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   292 
       
   293     TUint32 audioBitRate = iFileAudio->AudioBitRate();
       
   294     
       
   295     __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::AudioBitRateL", audioBitRate )
       
   296     
       
   297     return audioBitRate;
       
   298     }
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CMccFileSourceImpl::DurationL()
       
   302 // 
       
   303 // Returns duration of current media clip
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 TTimeIntervalMicroSeconds CMccFileSourceImpl::DurationL()
       
   307     {
       
   308     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::DurationL" )
       
   309 
       
   310     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   311 
       
   312     // Audio and video might have different duration, take longer one
       
   313     //
       
   314     
       
   315     TTimeIntervalMicroSeconds duration = 0;
       
   316     
       
   317     if ( AudioInUse() )
       
   318 	    {
       
   319 	    duration = MilliToMicroSeconds( iFileAudio->Duration() );
       
   320 	    }
       
   321 	if ( VideoInUse() )
       
   322 		{
       
   323 		TTimeIntervalMicroSeconds videoDuration = 
       
   324 		    MilliToMicroSeconds( iFileVideo->Duration() );
       
   325 		duration = videoDuration > duration ? videoDuration : duration;
       
   326 		}
       
   327 		
       
   328     __FILESOURCE_CONTROLL_INT1("CMccFileSourceImpl::DurationL in micro=", 
       
   329     	duration.Int64())
       
   330     return duration;
       
   331     }
       
   332 
       
   333 // -----------------------------------------------------------------------------
       
   334 // CMccFileSourceImpl::VideoFrameSizeL()
       
   335 // 
       
   336 // Returns current video frame size
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 TSize CMccFileSourceImpl::VideoFrameSizeL()
       
   340     {        
       
   341     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFrameSizeL" )
       
   342        
       
   343     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   344     
       
   345     TSize size = iFileVideo->VideoFrameSize();
       
   346     
       
   347     __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::VideoFrameSizeL iWidth", 
       
   348                                 size.iWidth )
       
   349 	__FILESOURCE_CONTROLL_INT1("CMccFileSourceImpl::VideoFrameSizeL iHeight",
       
   350 								size.iHeight )   
       
   351 								
       
   352     return size;
       
   353     }
       
   354     
       
   355 // -----------------------------------------------------------------------------
       
   356 // CMccFileSourceImpl::VideoBitRateL()
       
   357 // 
       
   358 // Returns current video bitrate
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 TUint32 CMccFileSourceImpl::VideoBitRateL()
       
   362     {    
       
   363     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoBitRateL" )
       
   364 
       
   365     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   366 
       
   367     TUint32 audioBitRate = iFileAudio->AudioBitRate();
       
   368     
       
   369     // Average bitrate is for the whole stream, 
       
   370     // subtract audio average to get video average
       
   371     TUint32 averageBitRate = iFileVideo->StreamAverageBitRate() - audioBitRate;
       
   372     
       
   373     __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::VideoBitRateL, videoBitRate", 
       
   374                                averageBitRate )
       
   375 
       
   376     return averageBitRate;
       
   377     }
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // CMccFileSourceImpl::PositionL()
       
   381 // 
       
   382 // Returns current streaming position. If other stream is already at end
       
   383 // (zero pos) other ones position is used. Otherwise always less progressed
       
   384 // streams position is returned.
       
   385 // -----------------------------------------------------------------------------
       
   386 //
       
   387 TTimeIntervalMicroSeconds CMccFileSourceImpl::PositionL()
       
   388     {
       
   389     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PositionL" )
       
   390 
       
   391     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   392 
       
   393     TTimeIntervalMicroSeconds audioPosition = 0;
       
   394     TTimeIntervalMicroSeconds videoPosition = 0;
       
   395  
       
   396     if ( AudioInUse() )
       
   397 	    {
       
   398 	    audioPosition = MilliToMicroSeconds( iFileAudio->Position() );
       
   399 	    }
       
   400 	if ( VideoInUse() )
       
   401 		{
       
   402 		videoPosition = MilliToMicroSeconds( iFileVideo->Position() );
       
   403 		}
       
   404 		
       
   405     __FILESOURCE_CONTROLL_INT2( "CMccFileSourceImpl::PositionL in micro, audio:", 
       
   406                                 audioPosition.Int64(), 
       
   407                                 " video:", videoPosition.Int64() )
       
   408 
       
   409     if ( videoPosition.Int64() == 0 || audioPosition.Int64() == 0 )
       
   410         {
       
   411         return Max( videoPosition, audioPosition );
       
   412         }
       
   413     return Min( videoPosition, audioPosition );
       
   414     }
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // CMccFileSourceImpl::AudioFourCCL()
       
   418 // -----------------------------------------------------------------------------
       
   419 //    
       
   420 TFourCC CMccFileSourceImpl::AudioFourCCL()
       
   421     {
       
   422     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioFourCCL" )
       
   423 
       
   424     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   425     
       
   426     return iFileAudio->GetFourCC();
       
   427     }
       
   428 
       
   429 // -----------------------------------------------------------------------------
       
   430 // CMccFileSourceImpl::VideoFourCCL()
       
   431 // -----------------------------------------------------------------------------
       
   432 //	    
       
   433 TFourCC CMccFileSourceImpl::VideoFourCCL()
       
   434     {
       
   435     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFourCCL" )
       
   436 
       
   437     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   438     
       
   439     return iFileVideo->GetFourCC();
       
   440     }
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CMccFileSourceImpl::GetConfigKeyL()
       
   444 // -----------------------------------------------------------------------------
       
   445 //
       
   446 void CMccFileSourceImpl::GetConfigKeyL( TDes8& aConfigKey )
       
   447     {
       
   448     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::GetConfigKeyL" )
       
   449     
       
   450     __ASSERT_ALWAYS( iMP4Handle && VideoInUse(), User::Leave( KErrNotReady ) );
       
   451     
       
   452     HBufC8* configKey = iFileVideo->GetConfigKeyL();
       
   453     CleanupStack::PushL( configKey );
       
   454     __ASSERT_ALWAYS( configKey, User::Leave( KErrNotFound ) );
       
   455     __ASSERT_ALWAYS( configKey->Length() <= aConfigKey.MaxLength(), 
       
   456                      User::Leave( KErrOverflow ) );
       
   457     aConfigKey.Copy( *configKey );
       
   458     CleanupStack::PopAndDestroy( configKey );
       
   459     
       
   460     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::GetConfigKeyL, exit" )
       
   461     }
       
   462     
       
   463 // -----------------------------------------------------------------------------
       
   464 // CMccFileSourceImpl::PlayL()
       
   465 // 
       
   466 // Starts streaming from 3gp file
       
   467 // -----------------------------------------------------------------------------
       
   468 //
       
   469 void CMccFileSourceImpl::SourcePlayL( TBool aIgnoreEvents, TBool aFileChangeMode )
       
   470     {
       
   471     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePlayL" )
       
   472     
       
   473     __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
       
   474 
       
   475     if ( iCurrentState == EPlaying )
       
   476         {
       
   477         return;
       
   478         }
       
   479     
       
   480     // Start decision for both needs to be done before starting either one
       
   481     TBool videoStartNeeded = StartNeededL( *iFileVideo );
       
   482     TBool audioStartNeeded = StartNeededL( *iFileAudio );
       
   483     
       
   484 	if ( videoStartNeeded && !aFileChangeMode  )
       
   485     	{
       
   486     	iFileVideo->StartTimerL();
       
   487     	}
       
   488     	
       
   489 	if ( audioStartNeeded && !aFileChangeMode )
       
   490 	    {
       
   491     	iFileAudio->StartTimerL();	  
       
   492 	    }
       
   493 	
       
   494 	if ( !aIgnoreEvents )
       
   495 	    {   
       
   496     	if ( iCurrentState == EPaused )
       
   497     	    {
       
   498     	    SendStreamEventToClient( KMccEventCategoryStream, KMccStreamResumed );
       
   499     	    }
       
   500     	else
       
   501     	    {
       
   502     	    SendStreamEventToClient( KMccEventCategoryStream, KMccStreamStarted );
       
   503     	    }
       
   504 	    }
       
   505 	    
       
   506     iCurrentState = EPlaying;
       
   507     
       
   508     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePlayL, exit" )
       
   509     }
       
   510         
       
   511 // -----------------------------------------------------------------------------
       
   512 // CMccFileSourceImpl::SourcePauseL()
       
   513 // 
       
   514 // Pauses streaming by cancelling timers
       
   515 // -----------------------------------------------------------------------------
       
   516 //
       
   517 void CMccFileSourceImpl::SourcePauseL()
       
   518     {
       
   519     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePauseL" )
       
   520     
       
   521     if ( iCurrentState != EPlaying && iCurrentState != EWaitingPause ) 
       
   522     	{
       
   523     	return;
       
   524     	}
       
   525     	
       
   526  	if ( VideoInUse() )
       
   527     	{
       
   528     	iFileVideo->StopTimer();	
       
   529     	iFileVideo->Cleanup();
       
   530     	}
       
   531 	if ( AudioInUse() )
       
   532 	    {
       
   533 	    iFileAudio->StopTimer();	
       
   534     	iFileAudio->Cleanup();	    
       
   535 	    }
       
   536 	    
       
   537     StopEofTimer();	    
       
   538 	
       
   539 	// If pause was caused by eof, paused event is passed to all filesource users    
       
   540 	TUint32 eventNumData = 
       
   541 	    ( iCurrentState == EWaitingPause ) ? KMccAutomaticEvent : 0;
       
   542 	    
       
   543 	SendStreamEventToClient( KMccEventCategoryStream, 
       
   544 	                         KMccStreamPaused, 
       
   545 	                         KErrNone, 
       
   546 	                         eventNumData );
       
   547 	
       
   548     iCurrentState = EPaused;
       
   549     
       
   550     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePauseL, exit" )
       
   551 	}
       
   552 	
       
   553 // -----------------------------------------------------------------------------
       
   554 // CMccFileSourceImpl::PauseAudioL()
       
   555 // 
       
   556 // pause audio only
       
   557 // -----------------------------------------------------------------------------
       
   558 //
       
   559 void CMccFileSourceImpl::PauseAudioL( TInt aError )
       
   560 	{
       
   561 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseAudio" )
       
   562     
       
   563     if ( iCurrentState != EPlaying ) 
       
   564     	{
       
   565     	return;
       
   566     	}
       
   567     	
       
   568     if ( AudioInUse() )
       
   569 	    {
       
   570 	    iFileAudio->StopTimer();	
       
   571     	iFileAudio->Cleanup();	    
       
   572 	    }
       
   573 	    
       
   574 	if ( aError )
       
   575         {
       
   576         SendStreamEventToClient( KMccEventCategoryStream, 
       
   577                                  KMccStreamPaused, 
       
   578                                  aError, 
       
   579                                  KMccAutomaticEvent );
       
   580         }
       
   581 	else if ( !VideoInUse() || iFileVideo->IsPaused() )
       
   582 		{
       
   583 		// Initiate pause sequence only if all used media types are paused
       
   584 		
       
   585         StartEofTimerL();
       
   586 		}
       
   587     else
       
   588         {
       
   589         // NOP
       
   590         }
       
   591 		
       
   592     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseAudio, exit" )
       
   593 	}
       
   594 	
       
   595 // -----------------------------------------------------------------------------
       
   596 // CMccFileSourceImpl::PauseVideoL()
       
   597 // 
       
   598 // pause video only
       
   599 // -----------------------------------------------------------------------------
       
   600 //
       
   601 void CMccFileSourceImpl::PauseVideoL( TInt aError )
       
   602 	{
       
   603 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseVideo" )
       
   604     
       
   605     if ( iCurrentState != EPlaying ) 
       
   606     	{
       
   607     	return;
       
   608     	}
       
   609     	
       
   610  	if ( VideoInUse() )
       
   611     	{
       
   612     	iFileVideo->StopTimer();	
       
   613     	iFileVideo->Cleanup();
       
   614     	}	
       
   615     
       
   616     if ( aError )
       
   617         {
       
   618         SendStreamEventToClient( KMccEventCategoryStream, 
       
   619                                  KMccStreamPaused, 
       
   620                                  aError,
       
   621                                  KMccAutomaticEvent );
       
   622         }
       
   623     else if ( !AudioInUse() || iFileAudio->IsPaused() )
       
   624 		{ 
       
   625 		// Initiate pause sequence only if all used media types are paused
       
   626 		
       
   627         StartEofTimerL();
       
   628 		}
       
   629     else
       
   630         {
       
   631         // NOP
       
   632         }
       
   633 		
       
   634     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseVideo, exit" )
       
   635 	}
       
   636 
       
   637 // -----------------------------------------------------------------------------
       
   638 // CMccFileSourceImpl::StopL()
       
   639 // 
       
   640 // Stops streaming
       
   641 // -----------------------------------------------------------------------------
       
   642 //
       
   643 void CMccFileSourceImpl::SourceStopL( TBool aIgnoreEvents, TBool aFileChangeMode )
       
   644     {
       
   645     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceStopL" )
       
   646   
       
   647     if ( iCurrentState == EConstructed )
       
   648         {
       
   649         return;
       
   650         }
       
   651 
       
   652     DoCleanupL( aFileChangeMode );
       
   653 	
       
   654 	if ( !aIgnoreEvents )
       
   655 	    {
       
   656     	SendStreamEventToClient( KMccEventCategoryStream, KMccStreamStopped );
       
   657 	    }
       
   658 		
       
   659     iCurrentState = EStopped;
       
   660     
       
   661     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceStopL, exit" )
       
   662     }
       
   663 
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CMccFileSourceImpl::SourceDataTypeCode()
       
   667 // -----------------------------------------------------------------------------
       
   668 //
       
   669 TFourCC CMccFileSourceImpl::SourceDataTypeCode( TMediaId aMediaId )
       
   670 	{
       
   671 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceDataTypeCode" )
       
   672 
       
   673     if ( KUidMediaTypeVideo == aMediaId.iMediaType &&
       
   674          iFileVideo )
       
   675         {
       
   676         iIsVideo = ETrue;
       
   677         return iFileVideo->GetFourCC(); 
       
   678         }
       
   679     else if ( KUidMediaTypeAudio == aMediaId.iMediaType &&
       
   680         iFileAudio )
       
   681         {
       
   682         iIsAudio = ETrue;
       
   683         return iFileAudio->GetFourCC();
       
   684         }
       
   685     else
       
   686         {
       
   687         return TFourCC( NULL );
       
   688         }
       
   689 	}
       
   690 	
       
   691 // -----------------------------------------------------------------------------
       
   692 // CMccFileSourceImpl::SetSourceDataTypeCode()
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 TInt CMccFileSourceImpl::SetSourceDataTypeCode( 
       
   696 	TFourCC aCodec, 
       
   697     TMediaId aMediaId )
       
   698 	{
       
   699 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SetSourceDataTypeCode" )
       
   700 	
       
   701     if ( KUidMediaTypeVideo == aMediaId.iMediaType
       
   702     	&& VideoInUse()
       
   703         && aCodec == iFileVideo->GetFourCC() )
       
   704         {   
       
   705         return KErrNone;
       
   706         }
       
   707     else if ( KUidMediaTypeAudio == aMediaId.iMediaType 
       
   708     	&& AudioInUse()
       
   709         && aCodec == iFileAudio->GetFourCC() )
       
   710         {  
       
   711         return KErrNone;
       
   712         }
       
   713     else
       
   714 	    {
       
   715 	    return KErrNotSupported;
       
   716 	    } 
       
   717 	}	
       
   718 
       
   719 // -----------------------------------------------------------------------------
       
   720 // CMccFileSourceImpl::SourcePrimeL()
       
   721 // -----------------------------------------------------------------------------
       
   722 //
       
   723 void CMccFileSourceImpl::SourcePrimeL()
       
   724 	{
       
   725 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePrimeL" )
       
   726    
       
   727    	iCurrentState = EPrimed;	
       
   728 	SendStreamEventToClient( KMccEventCategoryStream, KMccStreamPrepared );
       
   729 	
       
   730 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePrimeL, exit" )
       
   731 	}
       
   732 	    
       
   733 // -----------------------------------------------------------------------------
       
   734 // CMccFileSourceImpl::FillBufferL()
       
   735 // -----------------------------------------------------------------------------
       
   736 //
       
   737 void CMccFileSourceImpl::FillBufferL( CMMFBuffer* aBuffer,
       
   738 						              MDataSink*  aConsumer,
       
   739 						              TMediaId    aMediaId )
       
   740 	{
       
   741 	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL" )
       
   742 
       
   743 	if ( aMediaId.iMediaType == KUidMediaTypeAudio &&
       
   744 	     AudioInUse() )
       
   745 		{
       
   746     	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, audio" )
       
   747     
       
   748     	iFileAudio->FillBufferL( aBuffer, aConsumer );
       
   749 		}
       
   750 	else if (aMediaId.iMediaType == KUidMediaTypeVideo &&
       
   751 	     VideoInUse() )
       
   752 		{
       
   753     	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, video" )    
       
   754        
       
   755 		iFileVideo->FillBufferL( aBuffer, aConsumer );
       
   756 		}
       
   757 	else
       
   758 		{
       
   759     	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, unknown media " ) 
       
   760 		User::Leave( KErrNotSupported );	
       
   761 		}
       
   762 	}
       
   763 
       
   764 // -----------------------------------------------------------------------------
       
   765 // CMccFileSourceImpl::SourceThreadLogon
       
   766 // -----------------------------------------------------------------------------
       
   767 //
       
   768 TInt CMccFileSourceImpl::SourceThreadLogon( MAsyncEventHandler& aEventHandler )
       
   769 	{
       
   770 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceThreadLogon" )
       
   771 
       
   772 	iAsyncEventHandler = static_cast<MAsyncEventHandler*>( &aEventHandler );
       
   773 	return KErrNone;
       
   774 	}
       
   775 
       
   776 // -----------------------------------------------------------------------------
       
   777 // CMccFileSourceImpl::SourceThreadLogoff
       
   778 // -----------------------------------------------------------------------------
       
   779 //		
       
   780 void CMccFileSourceImpl::SourceThreadLogoff()
       
   781 	{
       
   782 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceThreadLogoff" )
       
   783 
       
   784 	iAsyncEventHandler = NULL;
       
   785 	}
       
   786 		
       
   787 // -----------------------------------------------------------------------------
       
   788 // CMccFileSourceImpl::FileOpenErrorL
       
   789 // -----------------------------------------------------------------------------
       
   790 //	
       
   791 void CMccFileSourceImpl::FileOpenErrorL( MP4Err error )
       
   792 	{
       
   793 	iMP4Handle = NULL;
       
   794 	if ( error == MP4_OUT_OF_MEMORY )
       
   795 		{
       
   796 		User::Leave( KErrNoMemory );	
       
   797 		}
       
   798 	else
       
   799 		{
       
   800 		User::Leave( KErrGeneral );	
       
   801 		}
       
   802 	}
       
   803 	
       
   804 // -----------------------------------------------------------------------------
       
   805 // CMccFileSourceImpl::MilliToMicroSeconds
       
   806 // -----------------------------------------------------------------------------
       
   807 //	  	
       
   808 TTimeIntervalMicroSeconds CMccFileSourceImpl::MilliToMicroSeconds( 
       
   809     TUint32 aMilliSeconds )
       
   810 	{
       
   811 	return TTimeIntervalMicroSeconds( (TInt64) aMilliSeconds * KMccMicroToMilliConst );
       
   812 	}
       
   813 	
       
   814 // -----------------------------------------------------------------------------
       
   815 // CMccFileSourceImpl::MicroToMilliSeconds
       
   816 // -----------------------------------------------------------------------------
       
   817 //	  		
       
   818 TUint32 CMccFileSourceImpl::MicroToMilliSeconds( 
       
   819     TTimeIntervalMicroSeconds aMicroSeconds )
       
   820 	{
       
   821 	return ( aMicroSeconds.Int64() / KMccMicroToMilliConst );
       
   822 	}
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CMccFileSourceImpl::SetFileName()
       
   826 // -----------------------------------------------------------------------------
       
   827 //
       
   828 void CMccFileSourceImpl::SetFileName( const TFileName& aFileName )
       
   829 	{
       
   830 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SetFileName" )
       
   831 
       
   832 	iFileName.Copy( aFileName );
       
   833 	}
       
   834 
       
   835 // -----------------------------------------------------------------------------
       
   836 // CMccFileSourceImpl::OpenFileForStreamingL()
       
   837 // -----------------------------------------------------------------------------
       
   838 //	
       
   839 void CMccFileSourceImpl::OpenFileForStreamingL( TFileName aFileName )
       
   840 	{
       
   841 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileForStreamingL" )
       
   842 
       
   843     TFileName fullFileName;
       
   844     MP4Err error = MP4_OK;
       
   845     
       
   846     RFs fS;
       
   847     User::LeaveIfError( fS.Connect() );
       
   848 	CleanupClosePushL( fS );
       
   849     TParse fp;
       
   850     TInt err = fS.Parse( aFileName, fp );
       
   851     
       
   852     if ( err )
       
   853         {
       
   854         __FILESOURCE_CONTROLL_INT1( 
       
   855             "CMccFileSourceImpl::OpenFileForStreamingL file name parse error:", 
       
   856             err )
       
   857 	    User::Leave( err );
       
   858         }
       
   859 	
       
   860     fullFileName = fp.FullName();
       
   861   	CleanupStack::PopAndDestroy( &fS ); 
       
   862 	
       
   863 	this->SetFileName( aFileName );
       
   864 	
       
   865 	const TInt KMccZeroTerminatorLen = 1;
       
   866 	__ASSERT_ALWAYS( 
       
   867 	    fullFileName.Length() + KMccZeroTerminatorLen <= fullFileName.MaxLength(),
       
   868 	    User::Leave( KErrOverflow ) );
       
   869 	
       
   870   	error = MP4ParseOpen( &iMP4Handle, (wchar_t *) fullFileName.PtrZ() );
       
   871 
       
   872     if ( error != MP4_OK )
       
   873 	    {
       
   874         __FILESOURCE_CONTROLL_INT1( 
       
   875             "CMccFileSourceImpl::OpenFileForStreamingL parse open error:", 
       
   876             error )
       
   877 
       
   878 	    iMP4Handle = NULL;
       
   879 	   	User::Leave( KErrGeneral );
       
   880 	    }
       
   881 	
       
   882     TBool containAudio = iFileAudio->ParseUpdateAudioDescriptions( iMP4Handle );
       
   883     TBool containVideo = iFileVideo->ParseUpdateVideoDescriptions( iMP4Handle );
       
   884 			
       
   885 	if ( !containAudio && !containVideo )
       
   886 	    {
       
   887 	    __FILESOURCE_CONTROLL( 
       
   888 	        "CMccFileSourceImpl::OpenFileForStreamingL no audio/video" )
       
   889 	    
       
   890 	    MP4ParseClose( iMP4Handle );
       
   891 	    iMP4Handle = NULL;
       
   892 	   	User::Leave( KErrNotSupported );
       
   893 	    }
       
   894 	    
       
   895 	iFileAudio->SetFileHandle( iMP4Handle );
       
   896 	iFileVideo->SetFileHandle( iMP4Handle );	
       
   897 
       
   898 	iFileAudio->ParseUpdateStreamDescription( iMP4Handle );
       
   899 	iFileVideo->ParseUpdateStreamDescription( iMP4Handle );
       
   900 	
       
   901 	// If filecontainers are reused (i.e. filename is changed), 
       
   902 	// position has to be zeroed
       
   903 	SetPositionL( 0 );
       
   904 	
       
   905 	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileForStreamingL, exit" )
       
   906 	}
       
   907 
       
   908 // -----------------------------------------------------------------------------
       
   909 // CMccFileSourceImpl::SendStreamEventToClient()
       
   910 // -----------------------------------------------------------------------------
       
   911 //	
       
   912 void CMccFileSourceImpl::SendStreamEventToClient( 
       
   913     TMccEventCategory aEventCategory,
       
   914     TMccEventType aEventType,
       
   915     TInt aError,
       
   916     TUint32 aEventNumData )
       
   917     {
       
   918     __FILESOURCE_MEDIA( "CMccFileSourceImpl::SendStreamEventToClient" )
       
   919     
       
   920     if ( iAsyncEventHandler )
       
   921 	    {
       
   922 	    ClearEvent();
       
   923 	    
       
   924 	    iMccEvent.iEndpointId = iEndpointId;
       
   925 	    iMccEvent.iEventCategory = aEventCategory;
       
   926 	    iMccEvent.iEventType = aEventType;
       
   927 	    iMccEvent.iErrorCode = aError;
       
   928 	    iMccEvent.iEventNumData = aEventNumData;
       
   929 
       
   930 		TMccInternalEvent internalEvent( KMccFileSourceUid, 
       
   931 		                                 EMccInternalEventNone,
       
   932 		                                 iMccEvent );
       
   933 		                         
       
   934 		iAsyncEventHandler->SendEventToClient( internalEvent );
       
   935 	    }
       
   936 	else
       
   937 		{
       
   938 		__FILESOURCE_MEDIA( "CMccFileSourceImpl::SendStreamEventToClient, \
       
   939 		iAsyncEventHandler=NULL" )
       
   940 		}
       
   941     }	
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // CMccFileSourceImpl::AudioInUse()
       
   945 // -----------------------------------------------------------------------------
       
   946 //
       
   947 TBool CMccFileSourceImpl::AudioInUse() const
       
   948     {
       
   949     return ( iFileAudio && iIsAudio );
       
   950     }
       
   951     
       
   952 // -----------------------------------------------------------------------------
       
   953 // CMccFileSourceImpl::VideoInUse()
       
   954 // -----------------------------------------------------------------------------
       
   955 //
       
   956 TBool CMccFileSourceImpl::VideoInUse() const
       
   957     {
       
   958     return ( iFileVideo && iIsVideo );
       
   959     }
       
   960 
       
   961 // -----------------------------------------------------------------------------
       
   962 // CMccFileSourceImpl::DoCleanupL()
       
   963 // -----------------------------------------------------------------------------
       
   964 //   
       
   965 void CMccFileSourceImpl::DoCleanupL( TBool aFileChangeMode )
       
   966     {
       
   967     if ( VideoInUse() && !aFileChangeMode )
       
   968     	{
       
   969     	iFileVideo->StopTimer();
       
   970     	iFileVideo->ResetTimeL();
       
   971     	// clean the iConsumerBuffer and iConsumer,
       
   972     	// to prevent still send data after Stoped	
       
   973     	iFileVideo->Cleanup();
       
   974     	}
       
   975 	if ( AudioInUse() && !aFileChangeMode )
       
   976         {
       
   977 	    iFileAudio->StopTimer();
       
   978 	    iFileAudio->ResetTimeL();	
       
   979     	iFileAudio->Cleanup();	    
       
   980 	    }
       
   981     }
       
   982 
       
   983 // -----------------------------------------------------------------------------
       
   984 // CMccFileSourceImpl::StartEofTimerL()
       
   985 // -----------------------------------------------------------------------------
       
   986 //
       
   987 void CMccFileSourceImpl::StartEofTimerL()
       
   988     {
       
   989     StopEofTimer();
       
   990     
       
   991     TInt delayAfterStop( KMccMicroToMilliConst * DelayAfterStop() );
       
   992     
       
   993     __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::StartEofTimerL, microsecs:",
       
   994                                 delayAfterStop )
       
   995     
       
   996     iEofTimer = CMccEofTimer::NewL( this );
       
   997     
       
   998     iEofTimer->After( delayAfterStop );
       
   999     }
       
  1000 
       
  1001 // -----------------------------------------------------------------------------
       
  1002 // CMccFileSourceImpl::EofTimerExpiredL()
       
  1003 // -----------------------------------------------------------------------------
       
  1004 //
       
  1005 void CMccFileSourceImpl::EofTimerExpiredL()
       
  1006     {
       
  1007     __FILESOURCE_CONTROLL( "CMccFileSourceImpl::EofTimerExpiredL" );
       
  1008 
       
  1009     iCurrentState = EWaitingPause;
       
  1010 		
       
  1011     SendStreamEventToClient( KMccEventCategoryStreamControl, KMccStreamPaused );
       
  1012     }
       
  1013 
       
  1014 // -----------------------------------------------------------------------------
       
  1015 // CMccFileSourceImpl::StopEofTimer()
       
  1016 // -----------------------------------------------------------------------------
       
  1017 //
       
  1018 void CMccFileSourceImpl::StopEofTimer()
       
  1019 	{
       
  1020     if ( iEofTimer )
       
  1021         {
       
  1022         __FILESOURCE_CONTROLL( 
       
  1023             "CMccFileSourceImpl::StopEofTimer, cancel iEofTimer" )
       
  1024         iEofTimer->Cancel();
       
  1025         delete iEofTimer;
       
  1026         iEofTimer = NULL;
       
  1027         }
       
  1028 	}
       
  1029 	        
       
  1030 // -----------------------------------------------------------------------------
       
  1031 // CMccFileSourceImpl::SetDelayAfterStop()
       
  1032 // -----------------------------------------------------------------------------
       
  1033 //
       
  1034 void CMccFileSourceImpl::SetDelayAfterStop( TInt aDelay )
       
  1035     {
       
  1036     __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::SetDelayAfterStop aDelay:", 
       
  1037                                 aDelay )
       
  1038     iDelayAfterStop = aDelay;    
       
  1039     }
       
  1040     
       
  1041 // -----------------------------------------------------------------------------
       
  1042 // CMccFileSourceImpl::DelayAfterStop()
       
  1043 // -----------------------------------------------------------------------------
       
  1044 //
       
  1045 TInt CMccFileSourceImpl::DelayAfterStop( ) const
       
  1046     {
       
  1047     return iDelayAfterStop;
       
  1048     }
       
  1049 
       
  1050 // -----------------------------------------------------------------------------
       
  1051 // CMccFileSourceImpl::ClearEvent()
       
  1052 // -----------------------------------------------------------------------------
       
  1053 //
       
  1054 void CMccFileSourceImpl::ClearEvent()
       
  1055     {
       
  1056     iMccEvent = TMccEvent();
       
  1057     }
       
  1058 
       
  1059 // -----------------------------------------------------------------------------
       
  1060 // CMccFileSourceImpl::StartNeededL()
       
  1061 // Checks current file position and determines based on that whether starting
       
  1062 // of this media type is needed. If this media type is already at end (at zero
       
  1063 // pos) but other is not yet, this media type does not need starting.
       
  1064 // -----------------------------------------------------------------------------
       
  1065 //
       
  1066 TBool CMccFileSourceImpl::StartNeededL( CMccFileSourceTypeBase& aFileSource )
       
  1067     {
       
  1068     TBool startNeeded( ETrue );
       
  1069     TTimeIntervalMicroSeconds currentPosition = PositionL();
       
  1070     
       
  1071     if ( aFileSource.MediaType().iMediaType == KUidMediaTypeAudio )
       
  1072         {
       
  1073         startNeeded = AudioInUse();
       
  1074         }
       
  1075     if ( aFileSource.MediaType().iMediaType == KUidMediaTypeVideo )
       
  1076         {
       
  1077         startNeeded = VideoInUse();
       
  1078         }
       
  1079         
       
  1080     if ( startNeeded && 
       
  1081          currentPosition.Int64() > 0 && 
       
  1082          aFileSource.Position() == 0 )
       
  1083         {
       
  1084         startNeeded = EFalse;
       
  1085         }
       
  1086     
       
  1087     return startNeeded;
       
  1088     }
       
  1089     
       
  1090 #ifndef EKA2
       
  1091 // DLL interface code
       
  1092 EXPORT_C TInt E32Dll( TDllReason )
       
  1093     {
       
  1094     return KErrNone;
       
  1095     }
       
  1096 #endif