os/mm/mmplugins/mmfwplugins/src/Plugin/Controller/Video/AviPlayController/aviplaycontroller.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
sl@0
    17
#include "aviplaycontroller.h"
sl@0
    18
sl@0
    19
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
    20
#include "srtreader.h"
sl@0
    21
#include "mmfdevsubtitle.h"
sl@0
    22
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
    23
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
sl@0
    24
#include <mmf/common/mmfvideoenums.h>
sl@0
    25
#endif
sl@0
    26
	
sl@0
    27
const TInt KTestBufferSize = 0x10000; 
sl@0
    28
_LIT8(KXvidDecoderMimeType,"video/mp4v-es");
sl@0
    29
_LIT8(KAviVideoCodec,"XVID");
sl@0
    30
sl@0
    31
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
    32
_LIT(KSrtExtension, "srt");
sl@0
    33
_LIT(KSrtDecoder, "srtdecoder");
sl@0
    34
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
    35
sl@0
    36
sl@0
    37
//Table that maps given samplerate with the MMF samplerate
sl@0
    38
const TSampleRateTable KRateLookup[]=
sl@0
    39
								 {
sl@0
    40
									{96000,EMMFSampleRate96000Hz},
sl@0
    41
        							{88200,EMMFSampleRate88200Hz},
sl@0
    42
                   					{48000,EMMFSampleRate48000Hz},
sl@0
    43
			                   		{44100,EMMFSampleRate44100Hz},
sl@0
    44
				                  	{32000,EMMFSampleRate32000Hz},
sl@0
    45
				                  	{22050,EMMFSampleRate22050Hz},
sl@0
    46
				                  	{16000,EMMFSampleRate16000Hz},
sl@0
    47
				                  	{11025,EMMFSampleRate11025Hz},
sl@0
    48
				                  	{8000, EMMFSampleRate8000Hz}
sl@0
    49
                   				 };
sl@0
    50
sl@0
    51
sl@0
    52
//This method generates a panic internal to this dll.
sl@0
    53
void CAviPlayController::Panic(TInt aPanicCode)
sl@0
    54
	{
sl@0
    55
	_LIT(KAviPlayControllerPanicCategory, "AviPlayController");
sl@0
    56
	User::Panic(KAviPlayControllerPanicCategory, aPanicCode);
sl@0
    57
	}
sl@0
    58
sl@0
    59
	
sl@0
    60
//This function creates an object of CAviPlayController.
sl@0
    61
CAviPlayController* CAviPlayController::NewL()
sl@0
    62
	{
sl@0
    63
    CAviPlayController* self = new(ELeave)CAviPlayController();
sl@0
    64
	CleanupStack::PushL(self);
sl@0
    65
	self->ConstructL();
sl@0
    66
	CleanupStack::Pop(self);
sl@0
    67
	return self;
sl@0
    68
	}
sl@0
    69
sl@0
    70
sl@0
    71
//Default Constructor of CAviPlayController
sl@0
    72
CAviPlayController::CAviPlayController() :
sl@0
    73
	iVideoSurfaceSupport(NULL)
sl@0
    74
	{
sl@0
    75
	
sl@0
    76
	}
sl@0
    77
sl@0
    78
sl@0
    79
//Destructor of CAviPlayController.
sl@0
    80
CAviPlayController::~CAviPlayController()
sl@0
    81
	{
sl@0
    82
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
    83
	delete iSrtReader;
sl@0
    84
	delete iDevSubtitle;
sl@0
    85
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
    86
sl@0
    87
	iDisplayRegion.Close();
sl@0
    88
	iDerivedClipRegion.Close();
sl@0
    89
	delete iAviReader;
sl@0
    90
	delete iDevVideoPlay;
sl@0
    91
	delete iMessage;
sl@0
    92
	delete iEventHandler;
sl@0
    93
	delete iScreenGc;
sl@0
    94
	delete iScreenDev;
sl@0
    95
	RFbsSession::Disconnect();
sl@0
    96
	}
sl@0
    97
sl@0
    98
//This constructs the custom command parsers of CAviPlayController.
sl@0
    99
void CAviPlayController::ConstructL()
sl@0
   100
	{
sl@0
   101
	CMMFVideoPlayControllerCustomCommandParser* vidPlayConParser = CMMFVideoPlayControllerCustomCommandParser::NewL(*this);
sl@0
   102
	CleanupStack::PushL(vidPlayConParser);
sl@0
   103
	AddCustomCommandParserL(*vidPlayConParser);
sl@0
   104
	CleanupStack::Pop(vidPlayConParser);
sl@0
   105
	
sl@0
   106
	CMMFVideoControllerCustomCommandParser* vidConParser = CMMFVideoControllerCustomCommandParser::NewL(*this);
sl@0
   107
	CleanupStack::PushL(vidConParser);
sl@0
   108
	AddCustomCommandParserL(*vidConParser);
sl@0
   109
	CleanupStack::Pop(vidConParser);
sl@0
   110
sl@0
   111
	CMMFAudioPlayDeviceCustomCommandParser* audPlayDevParser = CMMFAudioPlayDeviceCustomCommandParser::NewL(*this);
sl@0
   112
	CleanupStack::PushL(audPlayDevParser);
sl@0
   113
	AddCustomCommandParserL(*audPlayDevParser);
sl@0
   114
	CleanupStack::Pop(audPlayDevParser);
sl@0
   115
sl@0
   116
	CMMFResourceNotificationCustomCommandParser* notiParser = CMMFResourceNotificationCustomCommandParser::NewL(*this);
sl@0
   117
	CleanupStack::PushL(notiParser);
sl@0
   118
	AddCustomCommandParserL(*notiParser);
sl@0
   119
	CleanupStack::Pop(notiParser);//audio resource Notification Parser
sl@0
   120
	
sl@0
   121
	CMMFVideoSetInitScreenCustomCommandParser* vidScrDevParser = CMMFVideoSetInitScreenCustomCommandParser::NewL(*this);
sl@0
   122
	CleanupStack::PushL(vidScrDevParser);
sl@0
   123
	AddCustomCommandParserL(*vidScrDevParser);
sl@0
   124
	CleanupStack::Pop(vidScrDevParser);
sl@0
   125
sl@0
   126
	CMMFVideoPlayControllerExtCustomCommandParser* vidPlayExtParser = CMMFVideoPlayControllerExtCustomCommandParser::NewL(*this);
sl@0
   127
	CleanupStack::PushL(vidPlayExtParser);
sl@0
   128
	AddCustomCommandParserL(*vidPlayExtParser);
sl@0
   129
	CleanupStack::Pop(vidPlayExtParser);
sl@0
   130
sl@0
   131
#ifdef SYMBIAN_BUILD_GCE	
sl@0
   132
	CMMFVideoPlaySurfaceSupportCustomCommandParser* vidPlaySurfaceSupParser = CMMFVideoPlaySurfaceSupportCustomCommandParser::NewL(*this);
sl@0
   133
	CleanupStack::PushL(vidPlaySurfaceSupParser);
sl@0
   134
	AddCustomCommandParserL(*vidPlaySurfaceSupParser);
sl@0
   135
	CleanupStack::Pop(vidPlaySurfaceSupParser);
sl@0
   136
#endif // SYMBIAN_BUILD_GCE
sl@0
   137
sl@0
   138
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
   139
	CMMFVideoPlaySubtitleSupportCustomCommandParser * vidPlaySubtitleSupParser = CMMFVideoPlaySubtitleSupportCustomCommandParser::NewL(*this);
sl@0
   140
	CleanupStack::PushL(vidPlaySubtitleSupParser);
sl@0
   141
	AddCustomCommandParserL(*vidPlaySubtitleSupParser);
sl@0
   142
	CleanupStack::Pop(vidPlaySubtitleSupParser);
sl@0
   143
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
   144
sl@0
   145
	iEventHandler = new(ELeave) CSourceSinkEventHandler(*this);
sl@0
   146
	iAudioEnabled = EFalse;
sl@0
   147
	User::LeaveIfError(RFbsSession::Connect());
sl@0
   148
	}
sl@0
   149
sl@0
   150
sl@0
   151
//Adds a data source to the controller
sl@0
   152
void CAviPlayController::AddDataSourceL(MDataSource& aDataSource)
sl@0
   153
	{
sl@0
   154
	if (iState != EStopped) 
sl@0
   155
		{
sl@0
   156
		User::Leave(KErrNotReady);
sl@0
   157
		}
sl@0
   158
	if (iClip)
sl@0
   159
		{
sl@0
   160
		User::Leave(KErrAlreadyExists);
sl@0
   161
		}
sl@0
   162
	if (aDataSource.DataSourceType()==KUidMmfFileSource)
sl@0
   163
		{
sl@0
   164
		iClip = static_cast<CMMFFile*>(&aDataSource);
sl@0
   165
		iAviReader = CAviReader::NewL(*iClip,*this);
sl@0
   166
		User::LeaveIfError(iClip->SourceThreadLogon(*iEventHandler));
sl@0
   167
		iAviReader->AudioEnabled(iAudioEnabled);
sl@0
   168
		}
sl@0
   169
	else 
sl@0
   170
		{
sl@0
   171
		User::Leave(KErrNotSupported);
sl@0
   172
		}
sl@0
   173
	TMMFEvent controllerEvent;
sl@0
   174
	controllerEvent.iEventType = KMMFEventCategoryVideoOpenComplete;
sl@0
   175
	controllerEvent.iErrorCode = KErrNone;
sl@0
   176
	DoSendEventToClient(controllerEvent);		
sl@0
   177
	}
sl@0
   178
sl@0
   179
 
sl@0
   180
//Adds a data sink to the controller
sl@0
   181
void CAviPlayController::AddDataSinkL(MDataSink& aDataSink)
sl@0
   182
	{
sl@0
   183
	if (iState != EStopped) 
sl@0
   184
    	{
sl@0
   185
    	User::Leave(KErrNotReady);	
sl@0
   186
    	}
sl@0
   187
    if(iDevSound)
sl@0
   188
    	{
sl@0
   189
    	User::Leave(KErrAlreadyExists);
sl@0
   190
    	}
sl@0
   191
    if (aDataSink.DataSinkType()!=KUidMmfAudioOutput) 
sl@0
   192
    	{
sl@0
   193
    	User::Leave(KErrNotSupported);	
sl@0
   194
    	}
sl@0
   195
	MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(&aDataSink);
sl@0
   196
    User::LeaveIfError(audioOutput->SinkThreadLogon(*iEventHandler));
sl@0
   197
    iDevSound = &(audioOutput->SoundDevice());
sl@0
   198
	iDevSound->SetPrioritySettings(iPrioritySettings);
sl@0
   199
	if (IsSecureDrmModeL())
sl@0
   200
		{
sl@0
   201
		User::LeaveIfError(iDevSound->SetClientThreadInfo(ClientThreadIdL()));
sl@0
   202
		}
sl@0
   203
sl@0
   204
	delete iScreenDev;
sl@0
   205
	iScreenDev = NULL;
sl@0
   206
	TRAPD(err, iScreenDev = CFbsScreenDevice::NewL(iScreenNumber,EColor16MA));
sl@0
   207
	if (err == KErrNotSupported)
sl@0
   208
		{
sl@0
   209
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(iScreenNumber,EColor16M));
sl@0
   210
		}
sl@0
   211
	if (err == KErrNotSupported)
sl@0
   212
		{
sl@0
   213
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(iScreenNumber,EColor64K));
sl@0
   214
		}
sl@0
   215
	if (err == KErrNotSupported)
sl@0
   216
		{
sl@0
   217
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(iScreenNumber,EColor4K));
sl@0
   218
		}
sl@0
   219
	if (err == KErrNotSupported)
sl@0
   220
		{
sl@0
   221
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(iScreenNumber,EColor256));
sl@0
   222
		}
sl@0
   223
	if (err == KErrNotSupported)
sl@0
   224
		{
sl@0
   225
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(iScreenNumber,EColor16MAP));
sl@0
   226
		}
sl@0
   227
				
sl@0
   228
	User::LeaveIfError(err);
sl@0
   229
	delete iScreenGc;
sl@0
   230
	iScreenGc = NULL;
sl@0
   231
	User::LeaveIfError(iScreenDev->CreateContext(iScreenGc));
sl@0
   232
	iScreenGc->SetPenColor(KRgbBlack);
sl@0
   233
	iScreenGc->SetBrushColor(KRgbWhite);
sl@0
   234
	iScreenGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
sl@0
   235
	delete iDevVideoPlay;
sl@0
   236
	iDevVideoPlay = NULL;
sl@0
   237
	iDevVideoPlay = CMMFDevVideoPlay::NewL(*this);
sl@0
   238
	iVideoDecoderInitialized = EFalse;
sl@0
   239
	}
sl@0
   240
sl@0
   241
sl@0
   242
//Removes the data source from the controller
sl@0
   243
void CAviPlayController::RemoveDataSourceL(MDataSource& aDataSource)
sl@0
   244
	{
sl@0
   245
	if (iState != EStopped) 
sl@0
   246
    	{
sl@0
   247
    	User::Leave(KErrNotReady);	
sl@0
   248
    	}
sl@0
   249
   	if (!iClip)
sl@0
   250
    	{
sl@0
   251
    	User::Leave(KErrNotReady);
sl@0
   252
    	}
sl@0
   253
    if (iClip != &aDataSource) 
sl@0
   254
	 	{
sl@0
   255
    	User::Leave(KErrArgument);
sl@0
   256
    	}
sl@0
   257
    else
sl@0
   258
    	{
sl@0
   259
    	delete iAviReader;
sl@0
   260
    	iAviReader = NULL;
sl@0
   261
    	iClip = NULL;
sl@0
   262
   		}
sl@0
   263
	}
sl@0
   264
sl@0
   265
sl@0
   266
//Removes the data sink from the controller
sl@0
   267
void CAviPlayController::RemoveDataSinkL(MDataSink& aDataSink)
sl@0
   268
	{
sl@0
   269
	if ((!iDevSound) || (iState!= EStopped))
sl@0
   270
		{
sl@0
   271
    	User::Leave(KErrNotReady);
sl@0
   272
    	}
sl@0
   273
	if (aDataSink.DataSinkType() !=	KUidMmfAudioOutput) 
sl@0
   274
		{
sl@0
   275
	   	User::Leave(KErrNotSupported);	
sl@0
   276
	   	}
sl@0
   277
	MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(&aDataSink);
sl@0
   278
	CMMFDevSound& devSound = audioOutput->SoundDevice();
sl@0
   279
	if (iDevSound != &devSound) 
sl@0
   280
		{
sl@0
   281
		User::Leave(KErrArgument);
sl@0
   282
		}
sl@0
   283
	else
sl@0
   284
		{
sl@0
   285
		iDevSound = NULL;
sl@0
   286
		}
sl@0
   287
	delete iDevVideoPlay;
sl@0
   288
   	iDevVideoPlay = NULL;
sl@0
   289
	delete iScreenDev;
sl@0
   290
	iScreenDev = NULL;
sl@0
   291
	}
sl@0
   292
sl@0
   293
sl@0
   294
//Resets the controller
sl@0
   295
void CAviPlayController::ResetL()
sl@0
   296
	{
sl@0
   297
	StopL();
sl@0
   298
	iDevSound = NULL;
sl@0
   299
	delete iDevVideoPlay;
sl@0
   300
   	iDevVideoPlay = NULL;
sl@0
   301
    iClip=NULL;
sl@0
   302
    delete iAviReader;
sl@0
   303
    iAviReader = NULL;
sl@0
   304
    delete iMessage;
sl@0
   305
    iMessage = NULL;
sl@0
   306
	}	
sl@0
   307
sl@0
   308
sl@0
   309
//Primes the controller
sl@0
   310
void CAviPlayController::PrimeL(TMMFMessage& aMessage)
sl@0
   311
	{
sl@0
   312
	if (iState != EStopped)  
sl@0
   313
		{
sl@0
   314
		User::Leave( KErrNotReady );	
sl@0
   315
		}
sl@0
   316
	if (!iClip)
sl@0
   317
		{
sl@0
   318
		User::Leave(KErrNotReady);
sl@0
   319
		}
sl@0
   320
	if(iAudioEnabled)
sl@0
   321
    	{
sl@0
   322
    	if(!iDevSound)
sl@0
   323
    		{
sl@0
   324
    		User::Leave(KErrNotReady);
sl@0
   325
    		}
sl@0
   326
    	}
sl@0
   327
    __ASSERT_ALWAYS((!iMessage),Panic(EBadCall));	
sl@0
   328
    iMessage = CMMFMessageHolder::NewL(aMessage);	
sl@0
   329
	TRAPD(err,StartPrimeL());
sl@0
   330
	if(err != KErrNone)
sl@0
   331
		{
sl@0
   332
		SendErrorToClient(err);
sl@0
   333
		}
sl@0
   334
	}
sl@0
   335
	
sl@0
   336
sl@0
   337
void CAviPlayController::PrimeL()
sl@0
   338
    {
sl@0
   339
    Panic(EBadCall);
sl@0
   340
    }
sl@0
   341
	
sl@0
   342
sl@0
   343
//Primes the controller
sl@0
   344
void CAviPlayController::StartPrimeL()
sl@0
   345
	{
sl@0
   346
	CheckAviReaderPresentL();
sl@0
   347
	CheckDevVideoPresentL();
sl@0
   348
    iAviReader->AudioEnabled(iAudioEnabled);
sl@0
   349
    iClip->SourcePrimeL();
sl@0
   350
    // Initialise Devsound
sl@0
   351
 	if (iAudioEnabled)
sl@0
   352
		{
sl@0
   353
		iDevSound->InitializeL(*this, EMMFStatePlaying);
sl@0
   354
	  	}
sl@0
   355
	if(!iVideoDecoderInitialized)
sl@0
   356
		{
sl@0
   357
		if (!iVideoSurfaceSupport)
sl@0
   358
			{
sl@0
   359
			if (LocateDecoderL(EFalse))
sl@0
   360
				{
sl@0
   361
				// Set the video destination as Screen.This will leave if the
sl@0
   362
				// plug-in does not support DSA.
sl@0
   363
				iDevVideoPlay->SetVideoDestScreenL(ETrue);
sl@0
   364
				// Initialize devvideoPlay
sl@0
   365
				iDevVideoPlay->Initialize();
sl@0
   366
				}
sl@0
   367
			else
sl@0
   368
				{
sl@0
   369
				// Inform client if we couldn't find a suitable decoder.
sl@0
   370
				SendErrorToClient(KErrNotFound);
sl@0
   371
				}
sl@0
   372
			}
sl@0
   373
		else
sl@0
   374
			{
sl@0
   375
			// Decoder already located, done in UseSurfaces
sl@0
   376
			iDevVideoPlay->Initialize();
sl@0
   377
			}
sl@0
   378
		}
sl@0
   379
	else
sl@0
   380
		{
sl@0
   381
		if(iAudioEnabled)
sl@0
   382
			{
sl@0
   383
			iDevVideoInitialized = ETrue;
sl@0
   384
			}
sl@0
   385
		else
sl@0
   386
			{
sl@0
   387
			if (iMessage)
sl@0
   388
				{
sl@0
   389
				iMessage->Complete(KErrNone);
sl@0
   390
				delete iMessage;
sl@0
   391
				iMessage = NULL;
sl@0
   392
				}
sl@0
   393
			}
sl@0
   394
		
sl@0
   395
		iState = EPrimed;
sl@0
   396
 		}
sl@0
   397
	}
sl@0
   398
sl@0
   399
TBool CAviPlayController::LocateDecoderL(TBool aUseSurfaces)
sl@0
   400
	{
sl@0
   401
	// Find the Decoder
sl@0
   402
 	RArray<TUid> foundDecodersArray;
sl@0
   403
	CleanupClosePushL(foundDecodersArray);
sl@0
   404
	iDevVideoPlay->FindDecodersL(KXvidDecoderMimeType,
sl@0
   405
								 0, //  post-processing
sl@0
   406
									//  support is not needed
sl@0
   407
								 foundDecodersArray,
sl@0
   408
								 EFalse);
sl@0
   409
	TBool suitableDecoderFound = EFalse;
sl@0
   410
	if(foundDecodersArray.Count() > 0)
sl@0
   411
		{
sl@0
   412
		TUncompressedVideoFormat reqOutFormat;
sl@0
   413
		// Prefer RGB over YUV in case of graphics surfaces.
sl@0
   414
		if (aUseSurfaces)
sl@0
   415
			{
sl@0
   416
			reqOutFormat.iDataFormat = ERgbRawData;	
sl@0
   417
			reqOutFormat.iRgbFormat = ERgb32bit888;
sl@0
   418
			}
sl@0
   419
		else
sl@0
   420
			{
sl@0
   421
			reqOutFormat.iDataFormat = ERgbFbsBitmap;	
sl@0
   422
			reqOutFormat.iRgbFormat = EFbsBitmapColor16M;
sl@0
   423
			}
sl@0
   424
		
sl@0
   425
		// Here, we pick a decoder that can handle the output format
sl@0
   426
		// required
sl@0
   427
		suitableDecoderFound =
sl@0
   428
			SelectFirstSuitableDecoderL(foundDecodersArray, reqOutFormat, aUseSurfaces);
sl@0
   429
		}
sl@0
   430
sl@0
   431
	CleanupStack::PopAndDestroy(&foundDecodersArray);
sl@0
   432
	return suitableDecoderFound;
sl@0
   433
	}
sl@0
   434
	
sl@0
   435
sl@0
   436
// Selection of a suitable decoder based on the output format required
sl@0
   437
sl@0
   438
TBool CAviPlayController::SelectFirstSuitableDecoderL(
sl@0
   439
	const RArray<TUid>& aDecodersArray,
sl@0
   440
	const TUncompressedVideoFormat& aRequiredOutputFormat,
sl@0
   441
#ifdef SYMBIAN_BUILD_GCE
sl@0
   442
	TBool aUseSurfaces
sl@0
   443
#else
sl@0
   444
	TBool /* aUseSurfaces */
sl@0
   445
#endif // SYMBIAN_BUILD_GCE
sl@0
   446
	)
sl@0
   447
	{
sl@0
   448
	RArray<TUncompressedVideoFormat> outputFormatsArray;
sl@0
   449
	CleanupClosePushL(outputFormatsArray);
sl@0
   450
	TBool suitableDecoderFound = EFalse;
sl@0
   451
	TInt numDecoders = aDecodersArray.Count();
sl@0
   452
	for (TInt i = 0; !suitableDecoderFound && i < numDecoders; i++)
sl@0
   453
		{
sl@0
   454
		iDecoderDeviceId = iDevVideoPlay->SelectDecoderL(aDecodersArray[i]);
sl@0
   455
		
sl@0
   456
		#ifdef SYMBIAN_BUILD_GCE	
sl@0
   457
			if (aUseSurfaces)
sl@0
   458
				{
sl@0
   459
				// try to access the interface for video surfaces in dev video
sl@0
   460
				iVideoSurfaceSupport = static_cast<MMMFVideoSurfaceSupport*>(iDevVideoPlay->CustomInterface(iDecoderDeviceId, KUidMMFVideoSurfaceSupport));
sl@0
   461
				
sl@0
   462
				if (!iVideoSurfaceSupport)
sl@0
   463
					{
sl@0
   464
					continue;
sl@0
   465
					}
sl@0
   466
				}
sl@0
   467
		#endif // SYMBIAN_BUILD_GCE
sl@0
   468
		
sl@0
   469
		iDevVideoPlay->GetOutputFormatListL(iDecoderDeviceId,
sl@0
   470
											outputFormatsArray);
sl@0
   471
		if (outputFormatsArray.Find(aRequiredOutputFormat) !=
sl@0
   472
			KErrNotFound)
sl@0
   473
			{
sl@0
   474
			iDevVideoPlay->SetOutputFormatL(iDecoderDeviceId,
sl@0
   475
											aRequiredOutputFormat);
sl@0
   476
				
sl@0
   477
#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
sl@0
   478
			CVideoDecoderInfo* pCVideoDecoderInfo =
sl@0
   479
				iDevVideoPlay->VideoDecoderInfoLC(aDecodersArray[i]);
sl@0
   480
			RArray<TInt> supportedScreensArray;
sl@0
   481
			CleanupClosePushL(supportedScreensArray);
sl@0
   482
			pCVideoDecoderInfo->GetSupportedScreensL(supportedScreensArray);
sl@0
   483
			// If supportedScreensArray.Count() is zero, it implies that
sl@0
   484
			// decoder does not support any specific screens and it should be
sl@0
   485
			// able to support any screen. Continue to initialize DevVideoPlay.
sl@0
   486
			TInt err = KErrNone;
sl@0
   487
			if(supportedScreensArray.Count() > 0)
sl@0
   488
				{
sl@0
   489
				// The decoder supports specific screens. Check if it supports
sl@0
   490
				// the screen number set by the client.
sl@0
   491
				err = supportedScreensArray.Find(iScreenNumber);
sl@0
   492
				}
sl@0
   493
			// If err is KErrNotFound, it implies that the decoder does not
sl@0
   494
			// support the given screen and hence not suitable for the client.
sl@0
   495
			// check if the next decoder in the list is suitable.
sl@0
   496
			if(KErrNotFound != err)
sl@0
   497
				{
sl@0
   498
				// Suitable decoder is found.
sl@0
   499
				iDevVideoInitialized = EFalse;
sl@0
   500
				suitableDecoderFound = ETrue;
sl@0
   501
				}
sl@0
   502
			// supportedScreensArray, pCVideoDecoderInfo
sl@0
   503
			CleanupStack::PopAndDestroy(2, pCVideoDecoderInfo);
sl@0
   504
#else
sl@0
   505
			iDevVideoInitialized = EFalse;
sl@0
   506
			suitableDecoderFound = ETrue;
sl@0
   507
#endif
sl@0
   508
			}
sl@0
   509
		outputFormatsArray.Reset();
sl@0
   510
		}
sl@0
   511
	CleanupStack::PopAndDestroy(&outputFormatsArray);
sl@0
   512
sl@0
   513
	return suitableDecoderFound;
sl@0
   514
	}
sl@0
   515
sl@0
   516
sl@0
   517
//Starts playing and transfers the data from data source to data sink.
sl@0
   518
void CAviPlayController::PlayL()
sl@0
   519
	{
sl@0
   520
	if (iState != EPrimed )
sl@0
   521
    	{
sl@0
   522
    	User::Leave(KErrNotReady);
sl@0
   523
    	}
sl@0
   524
	iClip->SourcePlayL();
sl@0
   525
	
sl@0
   526
	if (iVideoSurfaceSupport == NULL)
sl@0
   527
		{
sl@0
   528
		iDevVideoPlay->StartDirectScreenAccessL(iScreenRect,*iScreenDev,iDerivedClipRegion);
sl@0
   529
		}
sl@0
   530
	
sl@0
   531
    iDevVideoPlay->Start();	
sl@0
   532
    if(iAudioEnabled)
sl@0
   533
  		{
sl@0
   534
    	iDevSound->PlayInitL();	
sl@0
   535
    	iState = EAudioReadyToPlay;
sl@0
   536
    	}
sl@0
   537
    else
sl@0
   538
    	{
sl@0
   539
    	iState = EPlaying;
sl@0
   540
    	}	
sl@0
   541
    	
sl@0
   542
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
   543
    if (iDevSubtitle)
sl@0
   544
    	{
sl@0
   545
    	// subtitle enabled
sl@0
   546
    	iDevSubtitle->SetVideoPositionL(0);
sl@0
   547
    	iDevSubtitle->Start();
sl@0
   548
    	iDevSubtitleStarted = ETrue;
sl@0
   549
    	}
sl@0
   550
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
   551
   	}
sl@0
   552
sl@0
   553
sl@0
   554
//Pause playing and the data transfer from data source to data sink.
sl@0
   555
void CAviPlayController::PauseL()
sl@0
   556
    {
sl@0
   557
    User::Leave(KErrNotSupported);
sl@0
   558
	}
sl@0
   559
sl@0
   560
sl@0
   561
//Stops playing and the data transfer from data source to data sink.
sl@0
   562
void CAviPlayController::StopL()
sl@0
   563
	{
sl@0
   564
	if (iState == EStopped)
sl@0
   565
    	{
sl@0
   566
    	return;
sl@0
   567
    	}
sl@0
   568
sl@0
   569
	StopAudioL();
sl@0
   570
	StopVideoL();
sl@0
   571
	StopAviReaderL();
sl@0
   572
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
   573
    StopSubtitles();
sl@0
   574
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
   575
sl@0
   576
    iState = EStopped;
sl@0
   577
	}
sl@0
   578
sl@0
   579
sl@0
   580
//Returns the current playing position from devvideoplay.
sl@0
   581
TTimeIntervalMicroSeconds CAviPlayController::PositionL() const
sl@0
   582
	{
sl@0
   583
 	if (iState == EStopped)
sl@0
   584
    	{
sl@0
   585
    	return 0;
sl@0
   586
    	}
sl@0
   587
	CheckDevVideoPresentL();	
sl@0
   588
    return iDevVideoPlay->PlaybackPosition();
sl@0
   589
	}
sl@0
   590
sl@0
   591
sl@0
   592
//Set the position to play from.
sl@0
   593
void CAviPlayController::SetPositionL(const TTimeIntervalMicroSeconds& /*aPosition*/)
sl@0
   594
	{
sl@0
   595
	//This will leave with KErrNotsupported as there is no support for seeking 
sl@0
   596
	//position in an .avi file.
sl@0
   597
	User::Leave(KErrNotSupported);
sl@0
   598
	}
sl@0
   599
sl@0
   600
sl@0
   601
//Returns the duration of the clip.
sl@0
   602
TTimeIntervalMicroSeconds CAviPlayController::DurationL() const
sl@0
   603
	{
sl@0
   604
	CheckAviReaderPresentL();
sl@0
   605
	return iAviReader->Duration();
sl@0
   606
	}
sl@0
   607
sl@0
   608
sl@0
   609
//Handles a custom command.
sl@0
   610
void CAviPlayController::CustomCommand(TMMFMessage& aMessage)
sl@0
   611
	{
sl@0
   612
	aMessage.Complete(KErrNotSupported);
sl@0
   613
	}
sl@0
   614
sl@0
   615
sl@0
   616
//Sets the priority settings for devsound.
sl@0
   617
void CAviPlayController::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
sl@0
   618
	{
sl@0
   619
 	iPrioritySettings = aPrioritySettings;
sl@0
   620
    if (iDevSound)
sl@0
   621
    	{
sl@0
   622
    	iDevSound->SetPrioritySettings(aPrioritySettings);
sl@0
   623
    	}
sl@0
   624
	}
sl@0
   625
sl@0
   626
sl@0
   627
//Gets the number of meta entries in the clip.
sl@0
   628
void CAviPlayController::GetNumberOfMetaDataEntriesL(TInt& /*aNumberOfEntries*/)
sl@0
   629
	{
sl@0
   630
	//Support to get meta data is not present.so this will leave with KErrNotSupported.
sl@0
   631
	User::Leave(KErrNotSupported);
sl@0
   632
	}
sl@0
   633
sl@0
   634
sl@0
   635
sl@0
   636
//Gets a meta entry at a specified index.
sl@0
   637
CMMFMetaDataEntry* CAviPlayController::GetMetaDataEntryL(TInt /*aIndex*/)
sl@0
   638
	{
sl@0
   639
	//Support to get meta data is not present.so this will leave with KErrNotSupported. 
sl@0
   640
	User::Leave(KErrNotSupported);
sl@0
   641
	return NULL;
sl@0
   642
	}
sl@0
   643
sl@0
   644
//----------------------------------------------- //
sl@0
   645
// MMMFVideoPlayControllerCustomCommandImplementor //
sl@0
   646
//-----------------------------------------------//
sl@0
   647
sl@0
   648
sl@0
   649
//Sets the screen clip region
sl@0
   650
void CAviPlayController::MvpcUpdateDisplayRegionL(const TRegion& aRegion)
sl@0
   651
	{
sl@0
   652
	// Only update display region if not using graphics surfaces
sl@0
   653
	if (!iVideoSurfaceSupport)
sl@0
   654
		{
sl@0
   655
		iDisplayRegion.Copy(aRegion);
sl@0
   656
		UpdateClipRegion();
sl@0
   657
		}
sl@0
   658
	}
sl@0
   659
sl@0
   660
sl@0
   661
//Gets the previously requested frame
sl@0
   662
void CAviPlayController::MvpcGetFrameL(MMMFVideoFrameMessage& aMessage)
sl@0
   663
	{
sl@0
   664
	CFbsBitmap& bitmap = aMessage.GetBitmap();
sl@0
   665
	TRAPD(err, CopyFrameL(bitmap));
sl@0
   666
	aMessage.FrameReady(err);	
sl@0
   667
	}
sl@0
   668
sl@0
   669
sl@0
   670
//Copies the previously requested frame
sl@0
   671
void CAviPlayController::CopyFrameL(CFbsBitmap& aBitmap)
sl@0
   672
	{
sl@0
   673
	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
sl@0
   674
	CleanupStack::PushL(bitmap);
sl@0
   675
	User::LeaveIfError(aBitmap.Resize(bitmap->SizeInPixels()));
sl@0
   676
	CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(&aBitmap);
sl@0
   677
	CleanupStack::PushL(bitmapDevice);
sl@0
   678
	CFbsBitGc* gc = NULL;
sl@0
   679
	User::LeaveIfError(bitmapDevice->CreateContext(gc));
sl@0
   680
	gc->DrawBitmap(TPoint(0,0), bitmap);
sl@0
   681
	gc->Clear();
sl@0
   682
	delete gc;
sl@0
   683
	CleanupStack::PopAndDestroy(2,bitmap);//for bitmapdevice and bitmap.
sl@0
   684
	}
sl@0
   685
sl@0
   686
sl@0
   687
//Gets if audio is enabled during playing.
sl@0
   688
void CAviPlayController::MvpcGetAudioEnabledL(TBool& aEnabled)
sl@0
   689
	{
sl@0
   690
	CheckAviReaderPresentL();
sl@0
   691
	iAviReader->AudioEnabled(iAudioEnabled);
sl@0
   692
	aEnabled = iAudioEnabled;
sl@0
   693
	}
sl@0
   694
sl@0
   695
sl@0
   696
//Sets the display window on the screen.
sl@0
   697
void CAviPlayController::MvpcSetDisplayWindowL(const TRect& aWindowRect, const TRect& aClipRect)
sl@0
   698
	{
sl@0
   699
	if (iVideoSurfaceSupport != NULL)
sl@0
   700
		{
sl@0
   701
		User::Leave(KErrNotSupported);
sl@0
   702
		}
sl@0
   703
		
sl@0
   704
	iScreenRect= aWindowRect;
sl@0
   705
	iClipRect = aClipRect;
sl@0
   706
	ASSERT(iScreenGc);
sl@0
   707
	UpdateClipRegion();
sl@0
   708
	}
sl@0
   709
sl@0
   710
sl@0
   711
//Aborts or resumes direct screen access depends on the DSA event received
sl@0
   712
void CAviPlayController::MvpcDirectScreenAccessEventL(const TMMFDSAEvent aDSAEvent)
sl@0
   713
	{
sl@0
   714
	if (iVideoSurfaceSupport != NULL)
sl@0
   715
		{
sl@0
   716
		User::Leave(KErrNotSupported);
sl@0
   717
		}
sl@0
   718
		
sl@0
   719
	CheckDevVideoPresentL();
sl@0
   720
	if (aDSAEvent == EAbortDSA)
sl@0
   721
		{
sl@0
   722
		if(iState == EPlaying)
sl@0
   723
			{
sl@0
   724
			iDevVideoPlay->AbortDirectScreenAccess();
sl@0
   725
			}
sl@0
   726
		}
sl@0
   727
	else if (aDSAEvent == EResumeDSA)
sl@0
   728
		{
sl@0
   729
		if((iState == EPrimed)||(iState == EPlaying))
sl@0
   730
			{
sl@0
   731
			iDevVideoPlay->StartDirectScreenAccessL(iScreenRect,*iScreenDev,iDerivedClipRegion);
sl@0
   732
			}
sl@0
   733
		}
sl@0
   734
	}
sl@0
   735
sl@0
   736
//Plays videoclip within the playwindow set
sl@0
   737
void CAviPlayController::MvpcPlayL(const TTimeIntervalMicroSeconds& /*aBegin*/,const TTimeIntervalMicroSeconds& /*aEnd*/)
sl@0
   738
	{
sl@0
   739
	//This will leave with KErrNotSupported as there is no provision to
sl@0
   740
	// seek the position in an .avi file.
sl@0
   741
	User::Leave(KErrNotSupported);
sl@0
   742
	}
sl@0
   743
sl@0
   744
sl@0
   745
//Redraws the current frame
sl@0
   746
void CAviPlayController::MvpcRefreshFrameL()
sl@0
   747
	{
sl@0
   748
	CheckDevVideoPresentL();
sl@0
   749
	iDevVideoPlay->Redraw();
sl@0
   750
	}
sl@0
   751
sl@0
   752
sl@0
   753
//Gets the progress of loading video clip
sl@0
   754
void CAviPlayController::MvpcGetLoadingProgressL(TInt& /*aPercentage*/)
sl@0
   755
	{
sl@0
   756
	//This will leave with KErrNotSuuported as there is no support 
sl@0
   757
	User::Leave(KErrNotSupported);
sl@0
   758
	}
sl@0
   759
sl@0
   760
sl@0
   761
//Prepares the controller for recording.
sl@0
   762
void CAviPlayController::MvpcPrepare()
sl@0
   763
	{
sl@0
   764
	TMMFEvent controllerEvent;
sl@0
   765
	controllerEvent.iEventType = KMMFEventCategoryVideoPrepareComplete;
sl@0
   766
	controllerEvent.iErrorCode = KErrNone;
sl@0
   767
	DoSendEventToClient(controllerEvent);		
sl@0
   768
	}
sl@0
   769
sl@0
   770
sl@0
   771
//Rotates the video file on the screen with the rotation angle given.
sl@0
   772
void CAviPlayController::MvpcSetRotationL(TVideoRotation aRotation)
sl@0
   773
	{
sl@0
   774
	//this will leave with KErrNotSupported as the Xvid Hwdevice does not support post processing.
sl@0
   775
	iRotation = aRotation;
sl@0
   776
	User::Leave(KErrNotSupported);
sl@0
   777
	}
sl@0
   778
sl@0
   779
sl@0
   780
//Gets the rotation applied to the video file.
sl@0
   781
void CAviPlayController::MvpcGetRotationL(TVideoRotation& aRotation)
sl@0
   782
	{
sl@0
   783
	//this will leave with KErrNotSupported as the Xvid Hwdevice does not support post processing.
sl@0
   784
	aRotation = iRotation;
sl@0
   785
	User::Leave(KErrNotSupported);
sl@0
   786
	}
sl@0
   787
sl@0
   788
sl@0
   789
//Scales the the video file on the screen with the scaling parameters given.
sl@0
   790
void CAviPlayController::MvpcSetScaleFactorL(TReal32 aWidthPercentage, TReal32 aHeightPercentage, TBool aAntiAliasFiltering)
sl@0
   791
	{
sl@0
   792
	//this will leave with KErrNotSupported as the Xvid Hwdevice does not support post processing.
sl@0
   793
	iWidthPercentage = aWidthPercentage;
sl@0
   794
	iHeightPercentage = aHeightPercentage;
sl@0
   795
	iAntiAliasFiltering = aAntiAliasFiltering;
sl@0
   796
	User::Leave(KErrNotSupported);	
sl@0
   797
	}
sl@0
   798
sl@0
   799
sl@0
   800
//Gets the scale factor applied for the video file.
sl@0
   801
void CAviPlayController::MvpcGetScaleFactorL(TReal32& aWidthPercentage, TReal32& aHeightPercentage, TBool& aAntiAliasFiltering)
sl@0
   802
	{
sl@0
   803
	//this will leave with KErrNotSupported as the Xvid Hwdevice does not support post processing.
sl@0
   804
	aWidthPercentage = iWidthPercentage;
sl@0
   805
	aHeightPercentage = iHeightPercentage;
sl@0
   806
	aAntiAliasFiltering = iAntiAliasFiltering;
sl@0
   807
	User::Leave(KErrNotSupported);
sl@0
   808
	}
sl@0
   809
sl@0
   810
sl@0
   811
//Sets the crop options for the image.
sl@0
   812
void CAviPlayController::MvpcSetCropRegionL(const TRect& aCropRegion)
sl@0
   813
	{
sl@0
   814
	//this will leave with KErrNotSupported as the Xvid Hwdevice does not support post processing.
sl@0
   815
	iCropRect = aCropRegion;
sl@0
   816
	User::Leave(KErrNotSupported);
sl@0
   817
	}
sl@0
   818
sl@0
   819
sl@0
   820
//Gets the crop options of the image.
sl@0
   821
void CAviPlayController::MvpcGetCropRegionL(TRect& aCropRegion)
sl@0
   822
	{
sl@0
   823
	//this will leave with KErrNotSupported as the Xvid Hwdevice does not support post processing.
sl@0
   824
	aCropRegion = iCropRect;
sl@0
   825
	User::Leave(KErrNotSupported);
sl@0
   826
	}
sl@0
   827
sl@0
   828
sl@0
   829
//Sets the video frame rate for recording.
sl@0
   830
void CAviPlayController::MvcSetFrameRateL(TReal32 /*aFramesPerSecond*/)
sl@0
   831
	{
sl@0
   832
	//There are no apis available at devvideo level to do this.
sl@0
   833
	//so, this will leave with KErrNotSupported.
sl@0
   834
	User::Leave(KErrNotSupported);
sl@0
   835
	}
sl@0
   836
sl@0
   837
sl@0
   838
//Gets the video frame rate applied for playing 
sl@0
   839
void CAviPlayController::MvcGetFrameRateL(TReal32& aFramesPerSecond)
sl@0
   840
	{
sl@0
   841
	CheckAviReaderPresentL();
sl@0
   842
	iAviReader->FrameRate(aFramesPerSecond);
sl@0
   843
	}
sl@0
   844
sl@0
   845
sl@0
   846
//Gets the audio codec used for playing.
sl@0
   847
void CAviPlayController::MvcGetAudioCodecL(TFourCC& aCodec)
sl@0
   848
	{
sl@0
   849
	if (iAudioEnabled)
sl@0
   850
		{
sl@0
   851
		aCodec = KMMFFourCCCodePCM16;
sl@0
   852
		CheckAviReaderPresentL();
sl@0
   853
	 	iAviReader->AudioCodec(aCodec);
sl@0
   854
		}
sl@0
   855
	else
sl@0
   856
		{
sl@0
   857
		User::Leave(KErrNotSupported);
sl@0
   858
		}
sl@0
   859
	}
sl@0
   860
sl@0
   861
sl@0
   862
//Gets the video codec used for playing.
sl@0
   863
void CAviPlayController::MvcGetVideoMimeTypeL(TDes8& aMimeType)
sl@0
   864
	{
sl@0
   865
	CheckAviReaderPresentL();
sl@0
   866
	aMimeType = KAviVideoCodec;
sl@0
   867
	iAviReader->VideoMimeType(aMimeType);
sl@0
   868
	}
sl@0
   869
sl@0
   870
sl@0
   871
//Gets the video bit rate used for playing.
sl@0
   872
void CAviPlayController::MvcGetVideoBitRateL(TInt& /*aBitRate*/)
sl@0
   873
	{
sl@0
   874
	//There are no devvideo api's to do this.
sl@0
   875
	//so, leave with KErrNotSuported.
sl@0
   876
	User::Leave(KErrNotSupported);
sl@0
   877
	}
sl@0
   878
sl@0
   879
sl@0
   880
//Gets the audio bit rate used for playing.
sl@0
   881
void CAviPlayController::MvcGetAudioBitRateL(TInt& aBitRate)
sl@0
   882
	{
sl@0
   883
	CheckAviReaderPresentL();
sl@0
   884
	if(iAudioEnabled)
sl@0
   885
		{
sl@0
   886
		aBitRate = (iAviReader->BitsPerSample() * iAviReader->SampleRate()* iAviReader->Channels());
sl@0
   887
		}
sl@0
   888
	else
sl@0
   889
		{
sl@0
   890
		User::Leave(KErrNotSupported);	
sl@0
   891
		}	
sl@0
   892
	}
sl@0
   893
sl@0
   894
sl@0
   895
//Returns the video framesize of the file.
sl@0
   896
void CAviPlayController::MvcGetVideoFrameSizeL(TSize& aSize)
sl@0
   897
	{
sl@0
   898
	CheckAviReaderPresentL();
sl@0
   899
	iAviReader->VideoFrameSize(aSize);
sl@0
   900
	}
sl@0
   901
sl@0
   902
sl@0
   903
sl@0
   904
//Sets the volume during playing.
sl@0
   905
void CAviPlayController::MapdSetVolumeL(TInt aVolume)
sl@0
   906
	{
sl@0
   907
	if (iAudioEnabled)
sl@0
   908
		{
sl@0
   909
		CheckDevSoundPresentL();
sl@0
   910
		TInt maxVolume = iDevSound->MaxVolume();
sl@0
   911
		iDevSound->SetVolume(aVolume);
sl@0
   912
		}
sl@0
   913
	else
sl@0
   914
		{
sl@0
   915
		User::Leave(KErrNotSupported);
sl@0
   916
		}	
sl@0
   917
	}
sl@0
   918
sl@0
   919
sl@0
   920
//Gets the maximum audio volume for playing.
sl@0
   921
void CAviPlayController::MapdGetMaxVolumeL(TInt& aMaxVolume)
sl@0
   922
	{
sl@0
   923
	if(iAudioEnabled)
sl@0
   924
		{
sl@0
   925
		CheckDevSoundPresentL();
sl@0
   926
		aMaxVolume = iDevSound->MaxVolume();
sl@0
   927
		}
sl@0
   928
	else
sl@0
   929
		{
sl@0
   930
		User::Leave(KErrNotSupported);
sl@0
   931
		}	
sl@0
   932
	}
sl@0
   933
sl@0
   934
sl@0
   935
//Gets the volume for playing
sl@0
   936
void CAviPlayController::MapdGetVolumeL(TInt& aVolume)
sl@0
   937
	{
sl@0
   938
	if (iAudioEnabled)
sl@0
   939
		{
sl@0
   940
		CheckDevSoundPresentL();
sl@0
   941
		aVolume = iDevSound->Volume();
sl@0
   942
		}
sl@0
   943
	else
sl@0
   944
		{
sl@0
   945
		User::Leave(KErrNotSupported);
sl@0
   946
		}
sl@0
   947
	}
sl@0
   948
sl@0
   949
sl@0
   950
//Gets the volume ramp for playing
sl@0
   951
void CAviPlayController::MapdSetVolumeRampL(const TTimeIntervalMicroSeconds& aRampDuration)
sl@0
   952
	{
sl@0
   953
	if (iAudioEnabled)
sl@0
   954
		{
sl@0
   955
		CheckDevSoundPresentL();
sl@0
   956
		iDevSound->SetVolumeRamp(aRampDuration);
sl@0
   957
		}
sl@0
   958
	else
sl@0
   959
		{
sl@0
   960
		User::Leave(KErrNotSupported);
sl@0
   961
		}	
sl@0
   962
	}
sl@0
   963
sl@0
   964
sl@0
   965
//Set the audio balance for playing.
sl@0
   966
void CAviPlayController::MapdSetBalanceL(TInt aBalance)
sl@0
   967
	{
sl@0
   968
	if (iAudioEnabled)
sl@0
   969
		{
sl@0
   970
		CheckDevSoundPresentL();
sl@0
   971
		if (aBalance < KMMFBalanceMaxLeft)
sl@0
   972
			{
sl@0
   973
    		aBalance = KMMFBalanceMaxLeft;	
sl@0
   974
    		}
sl@0
   975
		else if (aBalance > KMMFBalanceMaxRight)
sl@0
   976
			{
sl@0
   977
			aBalance = KMMFBalanceMaxRight;
sl@0
   978
			}
sl@0
   979
		TInt left = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight);
sl@0
   980
		TInt right = 100 - left;
sl@0
   981
		iDevSound->SetPlayBalanceL(left, right);
sl@0
   982
		}
sl@0
   983
	else
sl@0
   984
		{
sl@0
   985
		User::Leave(KErrNotSupported);
sl@0
   986
		}	
sl@0
   987
	}
sl@0
   988
sl@0
   989
sl@0
   990
//Get the audio balance applied for playing
sl@0
   991
void CAviPlayController::MapdGetBalanceL(TInt& aBalance)
sl@0
   992
	{
sl@0
   993
	if (iAudioEnabled)
sl@0
   994
		{
sl@0
   995
		CheckDevSoundPresentL();
sl@0
   996
		TInt left = 50; // arbitrary values 
sl@0
   997
		TInt right = 50;
sl@0
   998
		iDevSound->GetPlayBalanceL(left, right); 
sl@0
   999
		if ((left > 0) && (right > 0))
sl@0
  1000
			{
sl@0
  1001
			aBalance = (left * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight;
sl@0
  1002
			}
sl@0
  1003
		else if ((left == 0) && (right == 0))
sl@0
  1004
			{
sl@0
  1005
			aBalance = 0;
sl@0
  1006
			}
sl@0
  1007
		else if ((left == 0) && (right > 0))
sl@0
  1008
			{
sl@0
  1009
			aBalance = 100;
sl@0
  1010
			}
sl@0
  1011
		else if ((left > 0) && (right == 0))
sl@0
  1012
			{
sl@0
  1013
			aBalance = -100;
sl@0
  1014
			}
sl@0
  1015
		}
sl@0
  1016
	else
sl@0
  1017
		{
sl@0
  1018
		User::Leave(KErrNotSupported);
sl@0
  1019
		}	
sl@0
  1020
	}
sl@0
  1021
	
sl@0
  1022
sl@0
  1023
//Checks if valid devsound object is present.
sl@0
  1024
void CAviPlayController::CheckDevSoundPresentL()
sl@0
  1025
	{
sl@0
  1026
	if (!iDevSound)
sl@0
  1027
		{
sl@0
  1028
		User::Leave(KErrNotReady);
sl@0
  1029
		}
sl@0
  1030
	}
sl@0
  1031
sl@0
  1032
sl@0
  1033
//Checks if valid devvideoplay object present
sl@0
  1034
void CAviPlayController::CheckDevVideoPresentL() const
sl@0
  1035
	{
sl@0
  1036
	if (iDevVideoPlay && iVideoFatalError)
sl@0
  1037
		{
sl@0
  1038
		// A fatal error occured. This will recreate the DevVideo instance and
sl@0
  1039
		// also will clear iVideoFatalError flag. We use the cast operator here
sl@0
  1040
		// as we need to modify member data.
sl@0
  1041
		const_cast<CAviPlayController*>(this)->RecreateDevVideoAfterFatalErrorL();
sl@0
  1042
		}
sl@0
  1043
	if (!iDevVideoPlay)
sl@0
  1044
		{
sl@0
  1045
		User::Leave(KErrNotReady);
sl@0
  1046
		}
sl@0
  1047
	}
sl@0
  1048
sl@0
  1049
sl@0
  1050
//Checks if valid avireader object present.
sl@0
  1051
void CAviPlayController::CheckAviReaderPresentL() const
sl@0
  1052
	{
sl@0
  1053
	if (!iAviReader)
sl@0
  1054
    	{
sl@0
  1055
    	User::Leave(KErrNotReady);
sl@0
  1056
    	}
sl@0
  1057
	}
sl@0
  1058
sl@0
  1059
sl@0
  1060
//New empty buffers are available for decoding.Fill the video buffer
sl@0
  1061
//with video data and send it for decoding.
sl@0
  1062
void CAviPlayController:: MdvpoNewBuffers()
sl@0
  1063
	{
sl@0
  1064
	TVideoInputBuffer* newBuffer = NULL;
sl@0
  1065
	ASSERT(iAviReader);
sl@0
  1066
	ASSERT(iDevVideoPlay);
sl@0
  1067
	if (!iAviReader->IsVideoInputEnd())
sl@0
  1068
		{			
sl@0
  1069
	   	// get a buffer of a minimum size from DevVideoPlay.
sl@0
  1070
    	TRAPD(error, newBuffer = iDevVideoPlay->GetBufferL(KTestBufferSize));
sl@0
  1071
		if (!newBuffer)
sl@0
  1072
			{
sl@0
  1073
			//Lack of free buffers are not considered as an error.Hence return.
sl@0
  1074
			return;
sl@0
  1075
			}
sl@0
  1076
		   	
sl@0
  1077
    	TRAP(error, iAviReader->FillVideoBufferL(newBuffer));
sl@0
  1078
    	if (error != KErrNone)
sl@0
  1079
			{
sl@0
  1080
			SendErrorToClient(error);
sl@0
  1081
			return;
sl@0
  1082
			}
sl@0
  1083
		if(iAviReader->IsVideoInputEnd())
sl@0
  1084
			{
sl@0
  1085
			TRAPD(error,iDevVideoPlay->WriteCodedDataL(newBuffer));
sl@0
  1086
			if (error!= KErrNone)
sl@0
  1087
				{
sl@0
  1088
				SendErrorToClient(error);
sl@0
  1089
				return;			
sl@0
  1090
				}
sl@0
  1091
			iDevVideoPlay->InputEnd();
sl@0
  1092
			}
sl@0
  1093
		}
sl@0
  1094
	}
sl@0
  1095
sl@0
  1096
sl@0
  1097
//Fatal error occured while decoding video.Send the error to client.
sl@0
  1098
void CAviPlayController::MdvpoFatalError(TInt aError)
sl@0
  1099
	{
sl@0
  1100
	// No need to stop Video as this call back already implies a video problem,
sl@0
  1101
	// therefore it is supposed to be stopped (trying to stop it twice will
sl@0
  1102
	// cause a panic in devvideo).
sl@0
  1103
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
  1104
	StopSubtitles();
sl@0
  1105
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
  1106
    TRAP_IGNORE(StopAudioL(); StopAviReaderL());
sl@0
  1107
	// At this point we have to recreate the DevVideo instance. Since it is not
sl@0
  1108
	// safe to delete the instance inside this error call back, we use a flag
sl@0
  1109
	// so the next time we need to use DevVideo it will be recreated.
sl@0
  1110
	iVideoFatalError = ETrue;
sl@0
  1111
	iDevVideoInitialized = EFalse;
sl@0
  1112
	iVideoDecoderInitialized = EFalse;
sl@0
  1113
	iState = EStopped;
sl@0
  1114
    SendErrorToClient(aError);
sl@0
  1115
    }
sl@0
  1116
sl@0
  1117
sl@0
  1118
//Notifies the client that there are one or more new pictures are available.
sl@0
  1119
void CAviPlayController::MdvpoNewPictures()
sl@0
  1120
	{
sl@0
  1121
    // dispose of the picture
sl@0
  1122
	TVideoPicture* thePicture= NULL;
sl@0
  1123
	ASSERT(iDevVideoPlay);
sl@0
  1124
	TRAPD(err, thePicture = iDevVideoPlay->NextPictureL());
sl@0
  1125
	if (err == KErrNone && thePicture != NULL)
sl@0
  1126
		{
sl@0
  1127
		iDevVideoPlay->ReturnPicture(thePicture);
sl@0
  1128
		}
sl@0
  1129
	}
sl@0
  1130
sl@0
  1131
sl@0
  1132
//Initialization complete for devvideoplay.If audio is not enabled
sl@0
  1133
//set state to EPrimed.
sl@0
  1134
void CAviPlayController::MdvpoInitComplete(TInt aError)
sl@0
  1135
	{
sl@0
  1136
   	if (aError != KErrNone)
sl@0
  1137
		{
sl@0
  1138
		SendErrorToClient(aError);
sl@0
  1139
		return;
sl@0
  1140
		}
sl@0
  1141
    iDevVideoInitialized = ETrue;
sl@0
  1142
	// if audio is enabled we need to wait for both the audio and video initializations
sl@0
  1143
	//before completing client's prime message.
sl@0
  1144
	CheckForInitComplete();	
sl@0
  1145
	}
sl@0
  1146
 
sl@0
  1147
sl@0
  1148
//End of the video data in the file.
sl@0
  1149
void CAviPlayController::MdvpoStreamEnd()
sl@0
  1150
	{
sl@0
  1151
	TRAP_IGNORE(StopL());
sl@0
  1152
	SendErrorToClient(KErrNone);
sl@0
  1153
	}
sl@0
  1154
sl@0
  1155
sl@0
  1156
//Intended for future use.Will panic if called.
sl@0
  1157
void CAviPlayController:: MdvpoReturnPicture(TVideoPicture* /*aPicture*/)
sl@0
  1158
	{
sl@0
  1159
    Panic(EBadCall);
sl@0
  1160
    }
sl@0
  1161
 
sl@0
  1162
sl@0
  1163
//Intended for future use.Will panic if called.
sl@0
  1164
void CAviPlayController::MdvpoSupplementalInformation(const TDesC8 &/*aData*/, const TTimeIntervalMicroSeconds &/*aTimestamp*/, const TPictureId &/*aPictureId*/)
sl@0
  1165
	{
sl@0
  1166
   	Panic(EBadCall);
sl@0
  1167
    }
sl@0
  1168
sl@0
  1169
sl@0
  1170
//Intended for future use.Will panic if called.
sl@0
  1171
void CAviPlayController:: MdvpoPictureLoss()
sl@0
  1172
	{  
sl@0
  1173
 	Panic(EBadCall);
sl@0
  1174
 	}
sl@0
  1175
sl@0
  1176
sl@0
  1177
//Intended for future use.Will panic if called.
sl@0
  1178
void CAviPlayController::MdvpoPictureLoss(const TArray< TPictureId > &/*aPictures*/)
sl@0
  1179
	{
sl@0
  1180
   	Panic(EBadCall);
sl@0
  1181
    }
sl@0
  1182
    
sl@0
  1183
sl@0
  1184
//Intended for future use.Will panic if called.
sl@0
  1185
void CAviPlayController:: MdvpoSliceLoss(TUint /*aFirstMacroblock*/, TUint /*aNumMacroblocks*/, const TPictureId &/*aPicture*/)
sl@0
  1186
    {
sl@0
  1187
   	Panic(EBadCall);
sl@0
  1188
    }
sl@0
  1189
    
sl@0
  1190
sl@0
  1191
//Intended for future use.Will panic if called.
sl@0
  1192
void CAviPlayController::MdvpoReferencePictureSelection(const TDesC8 &/*aSelectionData*/)
sl@0
  1193
    {
sl@0
  1194
    Panic(EBadCall);
sl@0
  1195
    }
sl@0
  1196
    
sl@0
  1197
sl@0
  1198
//Intended for future use.Will panic if called.
sl@0
  1199
void CAviPlayController::MdvpoTimedSnapshotComplete(TInt /*aError*/, TPictureData */*aPictureData*/, const TTimeIntervalMicroSeconds &/*aPresentationTimestamp*/, const TPictureId &/*aPictureId*/)
sl@0
  1200
    {
sl@0
  1201
    Panic(EBadCall);
sl@0
  1202
    }
sl@0
  1203
sl@0
  1204
//Sets the initial screen number for the video display
sl@0
  1205
void CAviPlayController::MvsdSetInitScreenNumber(TInt aScreenNumber)
sl@0
  1206
	{
sl@0
  1207
	iScreenNumber = aScreenNumber;
sl@0
  1208
	}
sl@0
  1209
sl@0
  1210
#ifdef SYMBIAN_BUILD_GCE
sl@0
  1211
void CAviPlayController::MvpssUseSurfacesL()
sl@0
  1212
	{
sl@0
  1213
	// UseSurfaces must happen before initialize
sl@0
  1214
	if (!iDevVideoPlay || iVideoDecoderInitialized)
sl@0
  1215
		{
sl@0
  1216
		User::Leave(KErrNotReady);
sl@0
  1217
		}
sl@0
  1218
sl@0
  1219
	// Calling UseSurfaces multiple times is allowed
sl@0
  1220
	
sl@0
  1221
	if (iVideoSurfaceSupport == NULL)
sl@0
  1222
		{
sl@0
  1223
		if (LocateDecoderL(ETrue) && iVideoSurfaceSupport != NULL)
sl@0
  1224
			{
sl@0
  1225
			iVideoSurfaceSupport->MmvssSetObserver(*this);
sl@0
  1226
			iVideoSurfaceSupport->MmvssUseSurfaces();
sl@0
  1227
			}			
sl@0
  1228
		}
sl@0
  1229
	
sl@0
  1230
	// iVideoSurfaceSupport will be updated in LocateDecoderL
sl@0
  1231
	if (iVideoSurfaceSupport == NULL)
sl@0
  1232
		{
sl@0
  1233
		User::Leave(KErrNotSupported);
sl@0
  1234
		}		
sl@0
  1235
	}
sl@0
  1236
	
sl@0
  1237
void CAviPlayController::MvpssGetSurfaceParametersL(TSurfaceId& aSurfaceId,	TRect& aCropRect,
sl@0
  1238
														TVideoAspectRatio& aPixelAspectRatio)
sl@0
  1239
	{
sl@0
  1240
	if (iVideoSurfaceSupport == NULL)
sl@0
  1241
		{
sl@0
  1242
		User::Leave(KErrNotSupported);
sl@0
  1243
		}
sl@0
  1244
sl@0
  1245
	iVideoSurfaceSupport->MmvssGetSurfaceParametersL(aSurfaceId, aCropRect, aPixelAspectRatio);
sl@0
  1246
	}
sl@0
  1247
	
sl@0
  1248
void CAviPlayController::MvpssSurfaceRemovedL(const TSurfaceId& aSurfaceId)
sl@0
  1249
	{
sl@0
  1250
	if (iVideoSurfaceSupport == NULL)
sl@0
  1251
		{
sl@0
  1252
		User::Leave(KErrNotSupported);
sl@0
  1253
		}
sl@0
  1254
	
sl@0
  1255
	iVideoSurfaceSupport->MmvssSurfaceRemovedL(aSurfaceId);
sl@0
  1256
	}
sl@0
  1257
sl@0
  1258
void CAviPlayController::MmvsoSurfaceCreated()
sl@0
  1259
	{
sl@0
  1260
	DoSendEventToClient(TMMFEvent(KMMFEventCategoryVideoSurfaceCreated, KErrNone));
sl@0
  1261
	}
sl@0
  1262
	
sl@0
  1263
void CAviPlayController::MmvsoSurfaceParametersChanged()
sl@0
  1264
	{
sl@0
  1265
	DoSendEventToClient(TMMFEvent(KMMFEventCategoryVideoSurfaceParametersChanged, KErrNone));
sl@0
  1266
	}
sl@0
  1267
sl@0
  1268
void CAviPlayController::MmvsoRemoveSurface()
sl@0
  1269
	{
sl@0
  1270
	DoSendEventToClient(TMMFEvent(KMMFEventCategoryVideoRemoveSurface, KErrNone));
sl@0
  1271
	}
sl@0
  1272
#endif // SYMBIAN_BUILD_GCE
sl@0
  1273
sl@0
  1274
//Devsound initialization is completed.Configure devsound capabilities. 
sl@0
  1275
void CAviPlayController::InitializeComplete(TInt aError)
sl@0
  1276
	{
sl@0
  1277
	TInt error = aError;
sl@0
  1278
   	if (error == KErrNone)
sl@0
  1279
		{
sl@0
  1280
		ASSERT(iDevSound);
sl@0
  1281
		TMMFCapabilities devSoundCaps = iDevSound->Capabilities();
sl@0
  1282
		TMMFCapabilities caps;
sl@0
  1283
		ASSERT(iAviReader);
sl@0
  1284
		TInt rate = iAviReader->SampleRate();
sl@0
  1285
		TBool found = EFalse;
sl@0
  1286
		for( TInt index =0; index < KNumSampleRates; index++)
sl@0
  1287
			{
sl@0
  1288
			if(rate == KRateLookup[index].iRate)
sl@0
  1289
				{
sl@0
  1290
				caps.iRate = KRateLookup[index].iRateEnum;
sl@0
  1291
				found = ETrue;
sl@0
  1292
				}
sl@0
  1293
			}
sl@0
  1294
    	if(!found)
sl@0
  1295
    		{
sl@0
  1296
    		error = KErrNotFound;
sl@0
  1297
    		}
sl@0
  1298
    	if(error == KErrNone)
sl@0
  1299
    		{
sl@0
  1300
    		caps.iChannels = iAviReader->Channels();
sl@0
  1301
	    	if (caps.iChannels == 1) 
sl@0
  1302
				{
sl@0
  1303
				caps.iChannels = EMMFMono;
sl@0
  1304
				}
sl@0
  1305
			else if (caps.iChannels == 2)
sl@0
  1306
				{
sl@0
  1307
				caps.iChannels = EMMFStereo;
sl@0
  1308
				}
sl@0
  1309
			else 
sl@0
  1310
				{
sl@0
  1311
				error = KErrNotFound;
sl@0
  1312
				}	
sl@0
  1313
    		}
sl@0
  1314
    	if(error == KErrNone)
sl@0
  1315
    		{
sl@0
  1316
    		caps.iEncoding = EMMFSoundEncoding16BitPCM;
sl@0
  1317
    		TRAP(error,iDevSound->SetConfigL(caps));
sl@0
  1318
        	if(error == KErrNone)
sl@0
  1319
				{
sl@0
  1320
				iDevSoundInitialized = ETrue;
sl@0
  1321
				CheckForInitComplete();	
sl@0
  1322
				}
sl@0
  1323
			}
sl@0
  1324
		}
sl@0
  1325
	else
sl@0
  1326
		{
sl@0
  1327
		SendErrorToClient(error);
sl@0
  1328
		}
sl@0
  1329
		
sl@0
  1330
   	 }
sl@0
  1331
sl@0
  1332
//Intended for future use.Will panic if called.
sl@0
  1333
void CAviPlayController::ToneFinished(TInt /*aError*/)
sl@0
  1334
   	{
sl@0
  1335
 	Panic(EBadCall);
sl@0
  1336
 	}
sl@0
  1337
sl@0
  1338
sl@0
  1339
//This is called when an empty audio buffer is available.Fill the buffer with audio data.
sl@0
  1340
void CAviPlayController::BufferToBeFilled(CMMFBuffer* aBuffer)
sl@0
  1341
	{
sl@0
  1342
	if (iState == EAudioReadyToPlay)
sl@0
  1343
		{
sl@0
  1344
		iState = EPlaying;	
sl@0
  1345
		}
sl@0
  1346
	ASSERT(iAviReader);
sl@0
  1347
	TRAPD(err, iAviReader->FillAudioBufferL(aBuffer));
sl@0
  1348
	//if error,send the error to client
sl@0
  1349
	if(err)
sl@0
  1350
		{
sl@0
  1351
		SendErrorToClient(err);
sl@0
  1352
		}
sl@0
  1353
	}
sl@0
  1354
sl@0
  1355
//This is called when an audio play completion is successfully played or otherwise
sl@0
  1356
void CAviPlayController::PlayError(TInt aError)
sl@0
  1357
 	{
sl@0
  1358
	ASSERT(iAviReader);
sl@0
  1359
	
sl@0
  1360
	// Ignore overflow when the end of audio is reached.
sl@0
  1361
	if(aError == KErrUnderflow && iAviReader->IsAudioInputEnd())
sl@0
  1362
		{
sl@0
  1363
		// audio has reached the end of the file
sl@0
  1364
		aError = KErrNone;
sl@0
  1365
		}
sl@0
  1366
	
sl@0
  1367
	// Controller will be stopped and play complete message sent when the video stream
sl@0
  1368
	// has ended, unless there is an error.
sl@0
  1369
	if (aError != KErrNone)
sl@0
  1370
		{
sl@0
  1371
		TRAP_IGNORE(StopL());
sl@0
  1372
		SendErrorToClient(aError);
sl@0
  1373
		}
sl@0
  1374
	}
sl@0
  1375
sl@0
  1376
//Will panic if called.Should not be called during playing
sl@0
  1377
void CAviPlayController::BufferToBeEmptied(CMMFBuffer* /*aBuffer*/)
sl@0
  1378
	 {
sl@0
  1379
	 Panic(EBadCall);
sl@0
  1380
	 }
sl@0
  1381
sl@0
  1382
sl@0
  1383
//Will panic if called.Should not be called during playing
sl@0
  1384
void CAviPlayController::RecordError(TInt /*aError*/)
sl@0
  1385
	 {
sl@0
  1386
     Panic(EBadCall);
sl@0
  1387
	 }
sl@0
  1388
sl@0
  1389
sl@0
  1390
//Will panic if called.Should not be called during playing
sl@0
  1391
void CAviPlayController::ConvertError(TInt /*aError*/)
sl@0
  1392
	 {
sl@0
  1393
	 Panic(EBadCall);
sl@0
  1394
	 }
sl@0
  1395
	 
sl@0
  1396
sl@0
  1397
//Will panic if called.Should not be called during playing
sl@0
  1398
void CAviPlayController::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /*aMsg*/)
sl@0
  1399
	 {
sl@0
  1400
	 Panic(EBadCall);
sl@0
  1401
	 }
sl@0
  1402
sl@0
  1403
sl@0
  1404
//Sends an event to client.
sl@0
  1405
void CAviPlayController::SendEventToClient(const TMMFEvent& aEvent)
sl@0
  1406
	{
sl@0
  1407
    DoSendEventToClient(aEvent);
sl@0
  1408
	}
sl@0
  1409
 
sl@0
  1410
sl@0
  1411
//This function is called when an empty audio buffer filled with audio data.
sl@0
  1412
//This can now be sent to devsound for decoding.
sl@0
  1413
void CAviPlayController::AudioBufferFilled()
sl@0
  1414
	{
sl@0
  1415
	ASSERT(iDevSound);
sl@0
  1416
	iDevSound->PlayData();
sl@0
  1417
	}
sl@0
  1418
sl@0
  1419
sl@0
  1420
//This function is called when an empty video buffer is filled with video data.
sl@0
  1421
//This can now be sent for decoding.If there is no data then inform devvideo
sl@0
  1422
//about end of video stream.
sl@0
  1423
void CAviPlayController::VideoBufferFilled(TVideoInputBuffer* aBuffer)
sl@0
  1424
	{
sl@0
  1425
	ASSERT(iDevVideoPlay);
sl@0
  1426
	ASSERT(iAviReader);
sl@0
  1427
	TRAPD(error,iDevVideoPlay->WriteCodedDataL(aBuffer));
sl@0
  1428
	if(error != KErrNone)
sl@0
  1429
		{
sl@0
  1430
		SendErrorToClient(error);
sl@0
  1431
		return;
sl@0
  1432
		}
sl@0
  1433
	if(iAviReader->IsVideoInputEnd())
sl@0
  1434
		{
sl@0
  1435
		iDevVideoPlay->InputEnd();
sl@0
  1436
		}
sl@0
  1437
	}
sl@0
  1438
sl@0
  1439
sl@0
  1440
sl@0
  1441
//This function is used when both audio and video are enabled for playing.
sl@0
  1442
//The State is set to EPrimed when initialization is completed on both DevSound and DevVideo 
sl@0
  1443
void CAviPlayController::CheckForInitComplete()
sl@0
  1444
 	{
sl@0
  1445
 	if(iAudioEnabled)
sl@0
  1446
		{
sl@0
  1447
 		if ((iDevVideoInitialized) &&(iDevSoundInitialized))
sl@0
  1448
 			{
sl@0
  1449
 			iState = EPrimed;
sl@0
  1450
 			if (iMessage)
sl@0
  1451
				{
sl@0
  1452
				iMessage->Complete(KErrNone);
sl@0
  1453
				delete iMessage;
sl@0
  1454
				iMessage = NULL;
sl@0
  1455
				}
sl@0
  1456
 			}
sl@0
  1457
 		}
sl@0
  1458
 	else
sl@0
  1459
 		{
sl@0
  1460
 		iState = EPrimed;
sl@0
  1461
 		 		
sl@0
  1462
 		if (iMessage)
sl@0
  1463
 			{
sl@0
  1464
 			iMessage->Complete(KErrNone);
sl@0
  1465
			delete iMessage;
sl@0
  1466
			iMessage = NULL;
sl@0
  1467
 			}
sl@0
  1468
 		}
sl@0
  1469
 	iVideoDecoderInitialized = ETrue;
sl@0
  1470
 	}
sl@0
  1471
sl@0
  1472
//Sends the error message to the client.
sl@0
  1473
void CAviPlayController::SendErrorToClient(TInt aError)  
sl@0
  1474
	{
sl@0
  1475
	if (iMessage)
sl@0
  1476
		{
sl@0
  1477
		iMessage->Complete(aError);
sl@0
  1478
		delete iMessage;
sl@0
  1479
		iMessage = NULL;
sl@0
  1480
		}
sl@0
  1481
	else
sl@0
  1482
		{
sl@0
  1483
		TMMFEvent controllerEvent;
sl@0
  1484
		controllerEvent.iEventType = KMMFEventCategoryPlaybackComplete;
sl@0
  1485
		controllerEvent.iErrorCode = aError;
sl@0
  1486
		DoSendEventToClient(controllerEvent);	
sl@0
  1487
		}
sl@0
  1488
	}
sl@0
  1489
sl@0
  1490
CAviPlayController::CMMFMessageHolder* CAviPlayController::CMMFMessageHolder::NewL(TMMFMessage& aMessage)
sl@0
  1491
	{
sl@0
  1492
	return new(ELeave) CMMFMessageHolder(aMessage);
sl@0
  1493
	}
sl@0
  1494
		
sl@0
  1495
void CAviPlayController::CMMFMessageHolder::Complete(TInt aError) 
sl@0
  1496
	{
sl@0
  1497
	iMessage.Complete(aError);
sl@0
  1498
	}
sl@0
  1499
	
sl@0
  1500
CAviPlayController::CMMFMessageHolder::CMMFMessageHolder(TMMFMessage& aMessage): CBase(), iMessage(aMessage)
sl@0
  1501
	{
sl@0
  1502
	}
sl@0
  1503
sl@0
  1504
sl@0
  1505
CAviPlayController::CSourceSinkEventHandler::CSourceSinkEventHandler(CAviPlayController& aParent):iParent(aParent)
sl@0
  1506
	{
sl@0
  1507
	}
sl@0
  1508
sl@0
  1509
CAviPlayController::CSourceSinkEventHandler::~CSourceSinkEventHandler()
sl@0
  1510
	{
sl@0
  1511
	}
sl@0
  1512
sl@0
  1513
TInt CAviPlayController::CSourceSinkEventHandler::SendEventToClient(const TMMFEvent& aEvent)
sl@0
  1514
	{
sl@0
  1515
	iParent.SendEventToClient(aEvent);
sl@0
  1516
	return KErrNone;
sl@0
  1517
	}
sl@0
  1518
sl@0
  1519
void CAviPlayController::MarnRegisterAsClientL(TUid aEventType, const TDesC8& aNotificationRegistrationData)
sl@0
  1520
	{
sl@0
  1521
	//If file is open, check if audio is enabled
sl@0
  1522
	if(iAviReader)
sl@0
  1523
		{
sl@0
  1524
		iAviReader->AudioEnabled(iAudioEnabled);
sl@0
  1525
		if(!iAudioEnabled)
sl@0
  1526
			{
sl@0
  1527
			User::Leave(KErrArgument);	
sl@0
  1528
			}
sl@0
  1529
		}
sl@0
  1530
	//[ precondition that we have a sink]
sl@0
  1531
	CheckDevSoundPresentL();
sl@0
  1532
	
sl@0
  1533
	//[register the notification ]
sl@0
  1534
	TInt err = iDevSound->RegisterAsClient(aEventType, aNotificationRegistrationData);
sl@0
  1535
	User::LeaveIfError(err);
sl@0
  1536
	}
sl@0
  1537
sl@0
  1538
void CAviPlayController::MarnCancelRegisterAsClientL(TUid aEventType)
sl@0
  1539
	{
sl@0
  1540
	//[ precondition that we have a sink]
sl@0
  1541
	CheckDevSoundPresentL();
sl@0
  1542
	
sl@0
  1543
	//[cancel the notification ]
sl@0
  1544
	TInt err = 	iDevSound->CancelRegisterAsClient(aEventType);
sl@0
  1545
	User::LeaveIfError(err);
sl@0
  1546
	}
sl@0
  1547
sl@0
  1548
void CAviPlayController::MarnGetResourceNotificationDataL(TUid aEventType, TDes8& aNotificationData)
sl@0
  1549
	{
sl@0
  1550
	//[ precondition that we have a sink]
sl@0
  1551
	CheckDevSoundPresentL();
sl@0
  1552
	
sl@0
  1553
	//[get the notification data]
sl@0
  1554
	TMMFTimeIntervalMicroSecondsPckg pckg;
sl@0
  1555
	TInt err = iDevSound->GetResourceNotificationData(aEventType, pckg);
sl@0
  1556
	User::LeaveIfError(err);
sl@0
  1557
	
sl@0
  1558
	// aNotificationData is a package buffer returned as TMMFTimeIntervalMicroSecondsPckg.
sl@0
  1559
	// The contents should be converted to an integer and interpreted as samples played,
sl@0
  1560
	// but not as a microsecond value. 
sl@0
  1561
	// As the client expects a position (in microseconds from the beginning
sl@0
  1562
	// of the clip) we need to convert the data depending on the sample rate.
sl@0
  1563
	// Potential issue if using the number of samples played with VBR sampling.
sl@0
  1564
	TUint rate = 0;
sl@0
  1565
	TMMFCapabilities caps = iDevSound->Config();
sl@0
  1566
	for( TInt i = 0; i < KNumSampleRates; i++)
sl@0
  1567
		{
sl@0
  1568
		if(caps.iRate == KRateLookup[i].iRateEnum)
sl@0
  1569
			{
sl@0
  1570
			rate = KRateLookup[i].iRate;
sl@0
  1571
			break;	
sl@0
  1572
			}
sl@0
  1573
		}
sl@0
  1574
	if(rate != 0)
sl@0
  1575
		{
sl@0
  1576
		// Convert the given number of samples using the sample rate
sl@0
  1577
		const TInt KMicroSecsInOneSec = 1000000;
sl@0
  1578
		TTimeIntervalMicroSeconds value = pckg();
sl@0
  1579
		value = TTimeIntervalMicroSeconds(value.Int64() * ((TReal)KMicroSecsInOneSec / rate));
sl@0
  1580
		pckg() = value;
sl@0
  1581
		}
sl@0
  1582
	else
sl@0
  1583
		{
sl@0
  1584
		User::Leave(KErrArgument);
sl@0
  1585
		}
sl@0
  1586
	aNotificationData = pckg;
sl@0
  1587
	}
sl@0
  1588
sl@0
  1589
void CAviPlayController::MarnWillResumePlayL()
sl@0
  1590
	{
sl@0
  1591
	//[ precondition that we have a sink]
sl@0
  1592
	CheckDevSoundPresentL();
sl@0
  1593
	
sl@0
  1594
	//[wait for the client to resume ]
sl@0
  1595
	TInt err = iDevSound->WillResumePlay();	
sl@0
  1596
	User::LeaveIfError(err);
sl@0
  1597
	}
sl@0
  1598
sl@0
  1599
// Stops video.
sl@0
  1600
void CAviPlayController::StopVideoL()
sl@0
  1601
	{
sl@0
  1602
	// If already stopped, do nothing
sl@0
  1603
	if (iState == EStopped)
sl@0
  1604
    	{
sl@0
  1605
    	return;
sl@0
  1606
    	}
sl@0
  1607
sl@0
  1608
	CheckDevVideoPresentL();
sl@0
  1609
	// AbortDirectScreenAccess and Stop can only be used if DevVideoPlay has
sl@0
  1610
	// been already initialized. If CheckDevVideoPresentL has just recreated
sl@0
  1611
	// the DevVideoPlay instance, no need to make these calls on DevVideoPlay.
sl@0
  1612
	if (iDevVideoInitialized)
sl@0
  1613
		{
sl@0
  1614
		if (iVideoSurfaceSupport == NULL)
sl@0
  1615
			{
sl@0
  1616
			iDevVideoPlay->AbortDirectScreenAccess();
sl@0
  1617
			}
sl@0
  1618
sl@0
  1619
		iDevVideoPlay->Stop();
sl@0
  1620
		}
sl@0
  1621
	}
sl@0
  1622
sl@0
  1623
sl@0
  1624
// Stops audio (if enabled).
sl@0
  1625
void CAviPlayController::StopAudioL()
sl@0
  1626
	{
sl@0
  1627
	// If already stopped, do nothing
sl@0
  1628
	if (iState == EStopped || !iAudioEnabled)
sl@0
  1629
    	{
sl@0
  1630
    	return;
sl@0
  1631
    	}
sl@0
  1632
sl@0
  1633
	CheckDevSoundPresentL();
sl@0
  1634
	iDevSound->Stop();
sl@0
  1635
	iDevSoundInitialized = EFalse;
sl@0
  1636
	}
sl@0
  1637
sl@0
  1638
// Stops the data transfer from data source to data sink.
sl@0
  1639
void CAviPlayController::StopAviReaderL()
sl@0
  1640
	{
sl@0
  1641
	// If already stopped, do nothing
sl@0
  1642
	if (iState == EStopped)
sl@0
  1643
    	{
sl@0
  1644
    	return;
sl@0
  1645
    	}
sl@0
  1646
sl@0
  1647
	// Stop avi reader
sl@0
  1648
    CheckAviReaderPresentL();
sl@0
  1649
    iAviReader->ResetL();
sl@0
  1650
	}
sl@0
  1651
sl@0
  1652
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
  1653
// Stops DevSubtitle
sl@0
  1654
void CAviPlayController::StopSubtitles()
sl@0
  1655
	{
sl@0
  1656
    if (iDevSubtitle && iDevSubtitleStarted)
sl@0
  1657
    	{
sl@0
  1658
    	// stop subtitles if it was enabled
sl@0
  1659
    	iDevSubtitle->Stop();
sl@0
  1660
    	iDevSubtitleStarted = EFalse;
sl@0
  1661
    	}
sl@0
  1662
	}
sl@0
  1663
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
  1664
sl@0
  1665
// This non-const method is used to encapsulate non-const actions that need to
sl@0
  1666
// take place within a const method so there's no need to change the constness
sl@0
  1667
// definition of the caller method.
sl@0
  1668
void CAviPlayController::RecreateDevVideoAfterFatalErrorL()
sl@0
  1669
	{
sl@0
  1670
	iVideoFatalError = EFalse;
sl@0
  1671
	delete iDevVideoPlay;
sl@0
  1672
	iDevVideoPlay = NULL;
sl@0
  1673
	iDevVideoPlay = CMMFDevVideoPlay::NewL(*this);
sl@0
  1674
	iDevVideoInitialized = EFalse;
sl@0
  1675
	}
sl@0
  1676
sl@0
  1677
/*
sl@0
  1678
MMMFVideoPlayControllerExtCustomCommandImplementor
sl@0
  1679
*/
sl@0
  1680
sl@0
  1681
// Sets play velocity. that will be effective on next play
sl@0
  1682
void CAviPlayController::MvpecSetPlayVelocityL(TInt )
sl@0
  1683
	{
sl@0
  1684
	User::Leave(KErrNotSupported);
sl@0
  1685
	}
sl@0
  1686
sl@0
  1687
// returns play velocity
sl@0
  1688
TInt CAviPlayController::MvpecPlayVelocityL()
sl@0
  1689
	{
sl@0
  1690
	return 100; // return default play velocity.
sl@0
  1691
	}
sl@0
  1692
sl@0
  1693
//steps to the frame, relative to current frame
sl@0
  1694
void CAviPlayController::MvpecStepFrameL(TInt )
sl@0
  1695
	{
sl@0
  1696
	User::Leave(KErrNotSupported);
sl@0
  1697
	}
sl@0
  1698
sl@0
  1699
// return paly capabilities.
sl@0
  1700
void CAviPlayController::MvpecGetPlayRateCapabilitiesL(TVideoPlayRateCapabilities& aCapabilities)
sl@0
  1701
	{
sl@0
  1702
	// none of the capabilities are supported.
sl@0
  1703
	aCapabilities.iPlayBackward = EFalse;
sl@0
  1704
	aCapabilities.iPlayForward = EFalse;
sl@0
  1705
	aCapabilities.iStepBackward = EFalse;
sl@0
  1706
	aCapabilities.iStepForward = EFalse;
sl@0
  1707
	}
sl@0
  1708
sl@0
  1709
// enables or disables video.
sl@0
  1710
void CAviPlayController::MvpecSetVideoEnabledL(TBool )
sl@0
  1711
	{
sl@0
  1712
	User::Leave(KErrNotSupported);
sl@0
  1713
	}
sl@0
  1714
sl@0
  1715
// reutrns video enabled status.
sl@0
  1716
TBool CAviPlayController::MvpecVideoEnabledL()
sl@0
  1717
	{
sl@0
  1718
	// by default video is enabled.
sl@0
  1719
	return ETrue;
sl@0
  1720
	}
sl@0
  1721
sl@0
  1722
//enables or disables video.
sl@0
  1723
void CAviPlayController::MvpecSetAudioEnabledL(TBool )
sl@0
  1724
	{
sl@0
  1725
	User::Leave(KErrNotSupported);
sl@0
  1726
	}
sl@0
  1727
sl@0
  1728
// Scales video display as per the input parameters.
sl@0
  1729
void CAviPlayController::MvpecSetAutoScaleL(TAutoScaleType , TInt , TInt )
sl@0
  1730
	{
sl@0
  1731
	User::Leave(KErrNotSupported);
sl@0
  1732
	}
sl@0
  1733
sl@0
  1734
// Called when either iDisplayRegion or iClipRect are changed. The derived
sl@0
  1735
// clip region is the intersection of these. This method can be called
sl@0
  1736
// during playback, so the new region is passed immediately to DevVideo.
sl@0
  1737
void CAviPlayController::UpdateClipRegion()
sl@0
  1738
	{
sl@0
  1739
	iDerivedClipRegion.Copy(iDisplayRegion);
sl@0
  1740
	iDerivedClipRegion.ClipRect(iClipRect);
sl@0
  1741
	
sl@0
  1742
	if(iDevVideoInitialized)
sl@0
  1743
		{
sl@0
  1744
		// This isn't necessary in all cases, for instance there may be a
sl@0
  1745
		// direct screen access start/stop, which would also set the clipping
sl@0
  1746
		// region. This is added for completeness.
sl@0
  1747
		iDevVideoPlay->SetScreenClipRegion(iDerivedClipRegion);
sl@0
  1748
		}
sl@0
  1749
	
sl@0
  1750
	if(iScreenGc)
sl@0
  1751
		{
sl@0
  1752
		iScreenGc->SetClippingRegion(iDerivedClipRegion);
sl@0
  1753
		}
sl@0
  1754
	}
sl@0
  1755
sl@0
  1756
#ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
sl@0
  1757
// MMMFVideoPlaySubtitleSupportCustomCommandImplementor
sl@0
  1758
void CAviPlayController::MvpsusGetCrpParametersL(TInt aWindowId, TWsGraphicId& aId, TRect& aCrpRect)
sl@0
  1759
	{
sl@0
  1760
	if (!iDevSubtitle)
sl@0
  1761
		{
sl@0
  1762
		User::Leave(KErrNotReady);
sl@0
  1763
		}
sl@0
  1764
	iDevSubtitle->GetCrpParametersL(aWindowId, aId, aCrpRect);
sl@0
  1765
	}
sl@0
  1766
sl@0
  1767
void CAviPlayController::MvpsusAddSubtitleConfigL(const TMMFSubtitleWindowConfig& aConfig)
sl@0
  1768
	{
sl@0
  1769
	if (!iDevSubtitle)
sl@0
  1770
		{
sl@0
  1771
		User::Leave(KErrNotReady);
sl@0
  1772
		}
sl@0
  1773
	iDevSubtitle->AddSubtitleConfigL(aConfig);
sl@0
  1774
	
sl@0
  1775
	// Add successful, increment configuration count.
sl@0
  1776
	iSubtitleConfigCount++;
sl@0
  1777
	
sl@0
  1778
	if (iState == EPlaying && !iDevSubtitleStarted)
sl@0
  1779
		{
sl@0
  1780
		// video is playing but dev subtitle hasn't started, i.e. subtitle enabled during play
sl@0
  1781
		iDevSubtitle->SetVideoPositionL(iDevVideoPlay->PlaybackPosition());
sl@0
  1782
    	iDevSubtitle->Start();
sl@0
  1783
    	iDevSubtitleStarted = ETrue;
sl@0
  1784
		}
sl@0
  1785
	
sl@0
  1786
	// add subtitle config was successful
sl@0
  1787
	DoSendEventToClient(TMMFEvent(KMMFEventCategoryVideoSubtitleCrpReady, aConfig.iWindowId));
sl@0
  1788
	}
sl@0
  1789
sl@0
  1790
void CAviPlayController::MvpsusRemoveSubtitleConfigL(TInt aWindowId)
sl@0
  1791
	{
sl@0
  1792
	if (!iDevSubtitle)
sl@0
  1793
		{
sl@0
  1794
		User::Leave(KErrNotReady);
sl@0
  1795
		}
sl@0
  1796
	iDevSubtitle->RemoveSubtitleConfigL(aWindowId);
sl@0
  1797
	
sl@0
  1798
	// Remove successful, decrement configuration count.
sl@0
  1799
	iSubtitleConfigCount--;
sl@0
  1800
	
sl@0
  1801
	if (iSubtitleConfigCount == 0)
sl@0
  1802
		{
sl@0
  1803
		StopSubtitles();
sl@0
  1804
		}
sl@0
  1805
	}
sl@0
  1806
sl@0
  1807
void CAviPlayController::MvpsusUpdateSubtitleConfigL(const TMMFSubtitleWindowConfig& aConfig)
sl@0
  1808
	{
sl@0
  1809
	if (!iDevSubtitle)
sl@0
  1810
		{
sl@0
  1811
		User::Leave(KErrNotReady);
sl@0
  1812
		}
sl@0
  1813
	iDevSubtitle->UpdateSubtitleConfigL(aConfig);
sl@0
  1814
sl@0
  1815
	// update subtitle config was successful
sl@0
  1816
	DoSendEventToClient(TMMFEvent(KMMFEventCategoryVideoSubtitleCrpReady, aConfig.iWindowId));
sl@0
  1817
	}
sl@0
  1818
sl@0
  1819
void CAviPlayController::MvpsusGetSubtitlesAvailableL(TBool& aAvailable)
sl@0
  1820
	{
sl@0
  1821
	aAvailable = EFalse;
sl@0
  1822
	// first check if file source is added
sl@0
  1823
	if (iClip)
sl@0
  1824
		{
sl@0
  1825
		if (iSrtReader)
sl@0
  1826
			{
sl@0
  1827
			aAvailable = ETrue;
sl@0
  1828
			}
sl@0
  1829
		else
sl@0
  1830
			{
sl@0
  1831
			// Create and destroy a temporary SRT Reader object.
sl@0
  1832
			CSrtReader* tempReader = NULL;
sl@0
  1833
			TRAPD(err, tempReader = CreateSubtitleSourceL());
sl@0
  1834
			delete tempReader;
sl@0
  1835
			
sl@0
  1836
			// Subtitles are available if and only if CreateSubtitleSourceL had no errors.
sl@0
  1837
			aAvailable = (err == KErrNone);
sl@0
  1838
			
sl@0
  1839
			// If CreateSubtitleSourceL left with KErrNotFound then we do not leave; just report 
sl@0
  1840
			// subtitles as not available.
sl@0
  1841
			if (err != KErrNotFound && err != KErrNone)
sl@0
  1842
				{
sl@0
  1843
				User::Leave(err);
sl@0
  1844
				}
sl@0
  1845
			}
sl@0
  1846
		}
sl@0
  1847
	}
sl@0
  1848
sl@0
  1849
// create srt reader, return subtitle file name if a file clip has been added, leave if out of memory
sl@0
  1850
CSrtReader* CAviPlayController::CreateSubtitleSourceL()
sl@0
  1851
	{
sl@0
  1852
	const TDesC& filedrive = iClip->FileDrive();
sl@0
  1853
	const TDesC& filepath = iClip->FilePath();
sl@0
  1854
	const TDesC& filename = iClip->FileName();
sl@0
  1855
	
sl@0
  1856
	TFileName srtFileName;
sl@0
  1857
	
sl@0
  1858
	// Check that the srt file's filename length is not longer than the maximum filename length.  This
sl@0
  1859
	// can arise only when the extension "srt" is longer than the clip's file extension and the rest of 
sl@0
  1860
	// the name is very long.
sl@0
  1861
	// The 1 is added to account for the period "." before the extension.
sl@0
  1862
	if (filedrive.Length() + filepath.Length() + filename.Length() + KSrtExtension().Length() + 1 > srtFileName.MaxLength())
sl@0
  1863
		{
sl@0
  1864
		// File cannot exist on the filesystem
sl@0
  1865
		User::Leave(KErrNotFound);
sl@0
  1866
		}
sl@0
  1867
	
sl@0
  1868
	srtFileName.Format(_L("%S%S%S.%S"), &filedrive, &filepath, &filename, &KSrtExtension);
sl@0
  1869
	
sl@0
  1870
	CSrtReader* reader = CSrtReader::NewL(srtFileName);
sl@0
  1871
	
sl@0
  1872
	return reader;
sl@0
  1873
	}
sl@0
  1874
sl@0
  1875
void CAviPlayController::MvpsusDisableSubtitlesL()
sl@0
  1876
	{
sl@0
  1877
	// disable subtitles if subtitles was enabled
sl@0
  1878
	if (iDevSubtitle)
sl@0
  1879
		{
sl@0
  1880
		StopSubtitles();
sl@0
  1881
		delete iDevSubtitle;
sl@0
  1882
		iDevSubtitle = NULL;
sl@0
  1883
		
sl@0
  1884
		delete iSrtReader;
sl@0
  1885
		iSrtReader = NULL;
sl@0
  1886
		}
sl@0
  1887
	}
sl@0
  1888
sl@0
  1889
void CAviPlayController::MvpsusEnableSubtitlesL()
sl@0
  1890
	{
sl@0
  1891
	if (!iClip)
sl@0
  1892
		{
sl@0
  1893
		User::Leave(KErrNotReady);
sl@0
  1894
		}
sl@0
  1895
	if (iDevSubtitle)
sl@0
  1896
		{
sl@0
  1897
		User::Leave(KErrInUse);
sl@0
  1898
		}
sl@0
  1899
	CSrtReader* reader = CreateSubtitleSourceL();
sl@0
  1900
	CleanupStack::PushL(reader);
sl@0
  1901
	CMMFDevSubtitle* devSubtitle = CMMFDevSubtitle::NewLC(*reader);
sl@0
  1902
	devSubtitle->SelectDecoderL(KSrtDecoder);
sl@0
  1903
	
sl@0
  1904
	// subtitle was enabled sucessfully
sl@0
  1905
	// assign reader and devSubtitle to class and pop them from cleanup stack
sl@0
  1906
	CleanupStack::Pop(2, reader);
sl@0
  1907
	iDevSubtitle = devSubtitle;
sl@0
  1908
	iSrtReader = reader;
sl@0
  1909
	}
sl@0
  1910
sl@0
  1911
void CAviPlayController::MvpsusGetSubtitleLanguageL(TLanguage& aLanguage)
sl@0
  1912
	{
sl@0
  1913
	if (!iDevSubtitle)
sl@0
  1914
		{
sl@0
  1915
		User::Leave(KErrNotReady);
sl@0
  1916
		}
sl@0
  1917
	aLanguage = iDevSubtitle->SubtitleLanguageL();
sl@0
  1918
	}
sl@0
  1919
sl@0
  1920
void CAviPlayController::MvpsusGetSupportedSubtitleLanguagesL(RArray<TLanguage>& aLanguages)
sl@0
  1921
	{
sl@0
  1922
	if (!iDevSubtitle)
sl@0
  1923
		{
sl@0
  1924
		User::Leave(KErrNotReady);
sl@0
  1925
		}
sl@0
  1926
	iDevSubtitle->GetSupportedSubtitleLanguagesL(aLanguages);
sl@0
  1927
	}
sl@0
  1928
sl@0
  1929
void CAviPlayController::MvpsusSetSubtitleLanguageL(TLanguage aLanguage)
sl@0
  1930
	{
sl@0
  1931
	if (!iDevSubtitle)
sl@0
  1932
		{
sl@0
  1933
		User::Leave(KErrNotReady);
sl@0
  1934
		}
sl@0
  1935
	iDevSubtitle->SetSubtitleLanguageL(aLanguage);
sl@0
  1936
	}
sl@0
  1937
sl@0
  1938
#endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT