os/mm/mmplugins/lib3gp/wrapper/src/c3gpcompose.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2008-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
#include <e32debug.h>
sl@0
    17
#include <c3gplibrary.h>
sl@0
    18
sl@0
    19
#if defined (COMPOSE_DEBUG)
sl@0
    20
#define DEBUG_PRINT RDebug::Print
sl@0
    21
#else
sl@0
    22
#define DEBUG_PRINT
sl@0
    23
#endif
sl@0
    24
sl@0
    25
const TInt KMinWriteBufferMaxCount = 6;
sl@0
    26
_LIT(K3GPComposePanicName, "C3GPCompose");
sl@0
    27
sl@0
    28
// This is video base class containing common video properties.
sl@0
    29
T3GPVideoPropertiesBase::T3GPVideoPropertiesBase(T3GPVideoType aType,
sl@0
    30
		TUint aTimescale, const TSize& aSize) :
sl@0
    31
		iType(aType), iTimescale(aTimescale), iSize(aSize)
sl@0
    32
	{
sl@0
    33
	}
sl@0
    34
sl@0
    35
/**
sl@0
    36
This structure stores the common and MPEG-4 video specific properties of video data.
sl@0
    37
 
sl@0
    38
@param	aTimescale				Timescale of the video data.  This is the number of time units that 
sl@0
    39
 								pass in one second.
sl@0
    40
@param	aSize					Video width and height in pixels.
sl@0
    41
@param	aMaxBitRate 			Maximum video bit rate.
sl@0
    42
@param	aAvgBitRate				Average video bit rate.
sl@0
    43
@param	aDecoderSpecificInfo	MPEG-4 video DecoderSpecificInfo data stored in an ESDS atom.
sl@0
    44
*/
sl@0
    45
EXPORT_C T3GPVideoPropertiesMpeg4Video::T3GPVideoPropertiesMpeg4Video(TUint aTimescale,
sl@0
    46
		const TSize& aSize, TUint aMaxBitRate, TUint aAvgBitRate, const TDesC8& aDecoderSpecificInfo) :
sl@0
    47
		T3GPVideoPropertiesBase(E3GPMpeg4Video, aTimescale, aSize),
sl@0
    48
		iMaxBitRate(aMaxBitRate),
sl@0
    49
		iAvgBitRate(aAvgBitRate),
sl@0
    50
		iDecoderSpecificInfo(aDecoderSpecificInfo)
sl@0
    51
	{
sl@0
    52
	}
sl@0
    53
sl@0
    54
/**
sl@0
    55
This structure stores the common and H.263 specific properties of video data.
sl@0
    56
 
sl@0
    57
@param	aTimescale	Timescale of the video data.  This is the number of time units that 
sl@0
    58
					pass in one second.
sl@0
    59
@param	aSize		Video width and height in pixels.
sl@0
    60
@param	aVideoLevel	Indicates the H263 video level.
sl@0
    61
@param	aProfile	Indicates the H263 profile.
sl@0
    62
*/
sl@0
    63
EXPORT_C T3GPVideoPropertiesH263::T3GPVideoPropertiesH263(TUint aTimescale, const TSize& aSize,
sl@0
    64
		TInt aVideoLevel, TProfile aProfile) :
sl@0
    65
T3GPVideoPropertiesBase((aProfile == EProfile0) ? E3GPH263Profile0 : E3GPH263Profile3,
sl@0
    66
		aTimescale, aSize), iVideoLevel(aVideoLevel)
sl@0
    67
	{
sl@0
    68
	}
sl@0
    69
sl@0
    70
/**
sl@0
    71
This structure stores the common and AVC specific properties of video data.
sl@0
    72
 
sl@0
    73
@param	aTimescale				Timescale of the video data.  This is the number of time units that 
sl@0
    74
								pass in one second.
sl@0
    75
@param	aSize					Video width and height in pixels.
sl@0
    76
@param	aDecoderSpecificInfo	AVCDecoderConfigurationRecord data that will be stored in the avcC atom.
sl@0
    77
*/
sl@0
    78
EXPORT_C T3GPVideoPropertiesAvc::T3GPVideoPropertiesAvc(TUint aTimescale, const TSize& aSize,
sl@0
    79
		const TDesC8& aDecoderSpecificInfo) :
sl@0
    80
T3GPVideoPropertiesBase(E3GPAvcProfileBaseline, aTimescale, aSize),
sl@0
    81
iDecoderSpecificInfo(aDecoderSpecificInfo)
sl@0
    82
	{
sl@0
    83
	/*
sl@0
    84
		NOTE: Although Baseline profile is being set here, it's just used to indicate
sl@0
    85
		the fact that we have AVC data. The underlying 3GP lib does not differentiate
sl@0
    86
		between profiles when composing a file. It simply writes the contents of
sl@0
    87
		iDecoderSpecificInfo (which contains the profile amongst other things)
sl@0
    88
		verbatim into the "avcC" box.
sl@0
    89
	*/
sl@0
    90
	}
sl@0
    91
sl@0
    92
// This is audio base class containing common audio properties.
sl@0
    93
T3GPAudioPropertiesBase::T3GPAudioPropertiesBase(T3GPAudioType aType,
sl@0
    94
		TUint aTimescale, TInt aFramesPerSample) :
sl@0
    95
		iType(aType), iTimescale(aTimescale), iFramesPerSample(aFramesPerSample)
sl@0
    96
	{
sl@0
    97
	__ASSERT_ALWAYS((aTimescale > 0) && (aTimescale <= KMaxTUint16), User::Panic(K3GPComposePanicName, KErrOverflow));		
sl@0
    98
	}
sl@0
    99
sl@0
   100
/**
sl@0
   101
This structure stores the common and MPEG-4 audio-specific properties of audio data.
sl@0
   102
 
sl@0
   103
@param	aTimescale			Timescale of the audio data.  This is the number of time units that pass in one 
sl@0
   104
 							second. It must be smaller than 65536.
sl@0
   105
@param	aDecoderSpecificInfo MPEG-4 audio DecoderSpecificInfo data stored in an ESDS atom.
sl@0
   106
*/
sl@0
   107
EXPORT_C T3GPAudioPropertiesMpeg4Audio::T3GPAudioPropertiesMpeg4Audio(TUint aTimescale,
sl@0
   108
		const TDesC8& aDecoderSpecificInfo) :
sl@0
   109
		T3GPAudioPropertiesBase(E3GPMpeg4Audio, aTimescale, 0), 
sl@0
   110
		iDecoderSpecificInfo(aDecoderSpecificInfo)
sl@0
   111
	{
sl@0
   112
	}
sl@0
   113
sl@0
   114
/**
sl@0
   115
This structure stores the common and AMR-specific properties of audio data. 
sl@0
   116
 
sl@0
   117
@param	aTimescale			Timescale of the audio data.  This is the number of time units that pass in one 
sl@0
   118
 							second. It must be smaller than 65536.
sl@0
   119
@param	aFramesPerSample	Frames per sample.  It must be smaller than 256.
sl@0
   120
 							MPEG-4 audio has a fixed value of 1.
sl@0
   121
@param	aModeSet			AMR mode set.
sl@0
   122
@param	aCodec				AMR Speech Codec.
sl@0
   123
*/
sl@0
   124
EXPORT_C T3GPAudioPropertiesAmr::T3GPAudioPropertiesAmr(TUint aTimescale, TInt aFramesPerSample,
sl@0
   125
		TInt aModeSet, TSpeechCodec aCodec) :
sl@0
   126
		T3GPAudioPropertiesBase((aCodec == EAmrNB) ? E3GPAmrNB : E3GPAmrWB, 
sl@0
   127
		aTimescale, aFramesPerSample), iModeSet(aModeSet)
sl@0
   128
	{	
sl@0
   129
	__ASSERT_ALWAYS((aFramesPerSample > 0) && (aFramesPerSample <= KMaxTUint8), 
sl@0
   130
					User::Panic(K3GPComposePanicName, KErrOverflow));	
sl@0
   131
	}
sl@0
   132
sl@0
   133
/**
sl@0
   134
This structure stores the common and QCELP-specific properties of MPEG4 audio data. The storage mode is 
sl@0
   135
automatically set to MPEG4 Audio Sample Description Box mode.
sl@0
   136
 
sl@0
   137
@param	aTimescale			Timescale of the audio data.  This is the number of time units that pass in one 
sl@0
   138
 							second. It must be smaller than 65536.
sl@0
   139
@param	aFramesPerSample	Frames per sample.  It must be smaller than 512.
sl@0
   140
 							MPEG-4 audio has a fixed value of 1.
sl@0
   141
@param	aDecoderSpecificInfo MPEG-4 audio decoder specific information data stored in an ESDS atom.
sl@0
   142
*/
sl@0
   143
EXPORT_C T3GPAudioPropertiesQcelp::T3GPAudioPropertiesQcelp(TUint aTimescale, TInt aFramesPerSample,
sl@0
   144
		const TDesC8& aDecoderSpecificInfo) :
sl@0
   145
		T3GPAudioPropertiesBase(E3GPQcelp13K, aTimescale, aFramesPerSample),
sl@0
   146
		iMode(E3GPMP4AudioDescriptionBox),
sl@0
   147
		iDecoderSpecificInfo(aDecoderSpecificInfo)
sl@0
   148
	{
sl@0
   149
	__ASSERT_ALWAYS((aFramesPerSample > 0) && (aFramesPerSample <= KMaxTUint8), 
sl@0
   150
					User::Panic(K3GPComposePanicName, KErrOverflow));		
sl@0
   151
	}
sl@0
   152
sl@0
   153
/**
sl@0
   154
This structure stores the common and QCELP-specific properties of audio data.  
sl@0
   155
 
sl@0
   156
@param	aTimescale			Timescale of the audio data.  This is the number of time units that pass in one 
sl@0
   157
 							second. It must be smaller than 65536.
sl@0
   158
@param	aFramesPerSample	Frames per sample.  It must be smaller than 512.
sl@0
   159
 							MPEG-4 audio has a fixed value of 1.
sl@0
   160
*/
sl@0
   161
sl@0
   162
EXPORT_C T3GPAudioPropertiesQcelp::T3GPAudioPropertiesQcelp(TUint aTimescale, TInt aFramesPerSample) :
sl@0
   163
		T3GPAudioPropertiesBase(E3GPQcelp13K, aTimescale, aFramesPerSample),
sl@0
   164
		iMode(E3GPQcelpSampleEntryBox),
sl@0
   165
		iDecoderSpecificInfo(KNullDesC8)
sl@0
   166
	{
sl@0
   167
	__ASSERT_ALWAYS((aFramesPerSample > 0) && (aFramesPerSample <= KMaxTUint8), 
sl@0
   168
					User::Panic(K3GPComposePanicName, KErrOverflow));		
sl@0
   169
	}
sl@0
   170
sl@0
   171
/** 
sl@0
   172
Create an instance of 3GP composer using default buffer count and size.
sl@0
   173
sl@0
   174
The default values for buffer count and size are as follow:
sl@0
   175
Write Buffer Size is 2048 
sl@0
   176
Write Buffer Max Count is 15
sl@0
   177
sl@0
   178
@return A pointer to the newly created 3gp compose object.
sl@0
   179
sl@0
   180
@leave	KErrGeneral		General error.
sl@0
   181
@leave	KErrNoMemory	Out of memory.
sl@0
   182
sl@0
   183
@panic	C3GPCompose	KErrAbort	if clients do not a CActiveScheduler installed already.
sl@0
   184
*/
sl@0
   185
EXPORT_C C3GPCompose* C3GPCompose::NewL()
sl@0
   186
	{
sl@0
   187
	// Leave if no scheduler exists
sl@0
   188
	__ASSERT_ALWAYS ((CActiveScheduler::Current() != NULL), Panic(KErrAbort));
sl@0
   189
	C3GPCompose* self = new (ELeave) C3GPCompose(); 
sl@0
   190
	return self;
sl@0
   191
	}
sl@0
   192
sl@0
   193
/** 
sl@0
   194
Create an instance of 3GP composer, and let the user set a count limit and size of 
sl@0
   195
internal buffer for composition.
sl@0
   196
sl@0
   197
The default values for buffer count and size are as follow:
sl@0
   198
 Write Buffer Size is 2048 
sl@0
   199
 Write Buffer Max Count is 15
sl@0
   200
sl@0
   201
An increase of the buffer count and size will lead to a decrease of file I/O activities, thereby, 
sl@0
   202
improves the performance of the 3GP Composer at the expense of higher memory usage.
sl@0
   203
sl@0
   204
@param	aMediaWriteBufferSize Size of media data file output buffer (in bytes).
sl@0
   205
@param	aWriteBufferMaxCount	Maximum number of buffers (both media and meta) allowed before file 
sl@0
   206
 								output changes to synchronous (by default file writing is asynchronous 
sl@0
   207
 								operation).  A minimum value of 6 is enforced.
sl@0
   208
sl@0
   209
@return A pointer to the newly created 3gp compose object.
sl@0
   210
sl@0
   211
@leave	KErrGeneral		General error.
sl@0
   212
@leave	KErrNoMemory	Out of memory.
sl@0
   213
sl@0
   214
@panic	C3GPCompose	KErrAbort	if clients do not a CActiveScheduler installed already.
sl@0
   215
@panic	C3GPCompose	KErrArgument	if Write Buffer Size is less or equal to 0 or Write Buffer Max Count is
sl@0
   216
									less than 6.
sl@0
   217
 */
sl@0
   218
EXPORT_C C3GPCompose* C3GPCompose::NewL(TInt aMediaWriteBufferSize, TInt aWriteBufferMaxCount)
sl@0
   219
	{
sl@0
   220
	__ASSERT_ALWAYS ((aMediaWriteBufferSize > 0 && aWriteBufferMaxCount >= KMinWriteBufferMaxCount), 
sl@0
   221
					Panic(KErrArgument));
sl@0
   222
	// Leave if no scheduler exists
sl@0
   223
	__ASSERT_ALWAYS ((CActiveScheduler::Current() != NULL), Panic(KErrAbort));
sl@0
   224
	
sl@0
   225
	C3GPCompose* self = new (ELeave) C3GPCompose(aMediaWriteBufferSize, aWriteBufferMaxCount);
sl@0
   226
	return self;
sl@0
   227
	}
sl@0
   228
sl@0
   229
// First phase constructor
sl@0
   230
C3GPCompose::C3GPCompose(TInt aMediaWriteBufferSize, TInt aWriteBufferMaxCount) :
sl@0
   231
		iMediaWriteBufferSize(aMediaWriteBufferSize), 
sl@0
   232
		iWriteBufferMaxCount(aWriteBufferMaxCount),
sl@0
   233
		iDuplicateFileHandleCreated(EFalse)
sl@0
   234
	{
sl@0
   235
	}
sl@0
   236
sl@0
   237
/** 
sl@0
   238
This function initialises the 3GP composer for writing 3GP/3G2/MP4 data into a file.
sl@0
   239
Any combination of one video and one audio type is acceptable.  
sl@0
   240
sl@0
   241
Note: Ownership of aVideo and aAudio remains with the caller.  Both aVideo and aAudio are ready for 
sl@0
   242
deletion after C3GPCompose::Open returns.
sl@0
   243
sl@0
   244
@param	aFileFormat	Specifies the file format in which the data will be created.  Refer to 
sl@0
   245
 					T3GPFileFormatType for supported file format types.
sl@0
   246
@param 	aVideo 		Specifies the video stream to be used for video data.  The input data given will 
sl@0
   247
 					be inserted into 3GP file headers and is ready to be disposed when 
sl@0
   248
 					C3GPCompose::Open returns. See Video Properties Classes.
sl@0
   249
 					If aVideo is NULL, audio-only file will be composed.
sl@0
   250
@param 	aAudio 		Specifies the audio stream to be used for audio data.  The input data given will 
sl@0
   251
 					be inserted into 3GP file headers and is ready to be disposed when 
sl@0
   252
 					C3GPCompose::Open returns. See Audio Properties Classes.
sl@0
   253
 					If aAudio is NULL, video-only file will be composed.
sl@0
   254
@param	aFilename  	A full path name of the file to save the data to.  An empty path is not allowed.
sl@0
   255
@param	aFlags		Optional flags for composing preferences.  Refer to T3GPComposeFlag for supported flags.
sl@0
   256
 					The combined use of flags is acceptable.  For example:
sl@0
   257
 					E3GPLongClip | E3GPMetaDataLast 
sl@0
   258
sl@0
   259
@return KErrNone		if successful. Otherwise, returns one of the system wide error codes.
sl@0
   260
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   261
  		KErrNoMemory	if an attempt to allocate memory has failed;
sl@0
   262
  		KErrArgument	if neither video nor audio stream is specified;  
sl@0
   263
  		KErrAccessDenied	if opening file has failed;
sl@0
   264
  		KErrUnderflow	if the file name length is not greater than 0;
sl@0
   265
  		KErrInUse		if the composer is currently engaged; C3GPCompose::Complete must be called to 
sl@0
   266
  		 		 		finish the current composition before the composer can be re-initialised again.
sl@0
   267
*/
sl@0
   268
EXPORT_C TInt C3GPCompose::Open(T3GPFileFormatType aFileFormat,
sl@0
   269
		const T3GPVideoPropertiesBase* aVideo,
sl@0
   270
		const T3GPAudioPropertiesBase* aAudio,
sl@0
   271
		const TDesC& aFilename,
sl@0
   272
		TUint aFlags)
sl@0
   273
	{
sl@0
   274
	if (iHandler)
sl@0
   275
		{
sl@0
   276
		return KErrInUse;
sl@0
   277
		}
sl@0
   278
	if (aFilename.Length() <= 0)
sl@0
   279
		{
sl@0
   280
		return KErrUnderflow;
sl@0
   281
		}
sl@0
   282
	if (!aVideo && !aAudio)
sl@0
   283
		{
sl@0
   284
		// if neither video nor audio is supplied
sl@0
   285
		return KErrArgument;
sl@0
   286
		}
sl@0
   287
	
sl@0
   288
	// Create a zero terminated version of the file name
sl@0
   289
	RBuf fileName;	
sl@0
   290
	TInt err = fileName.Create(aFilename.Length() + 1);
sl@0
   291
	if (err == KErrNone)
sl@0
   292
		{
sl@0
   293
		fileName.Copy(aFilename);
sl@0
   294
		mp4_u16* mp4FileName = const_cast<mp4_u16*>(fileName.PtrZ());
sl@0
   295
		MP4Err mp4Err = MP4ComposeOpen(&iHandler, reinterpret_cast<MP4FileName>(mp4FileName), Mp4Type(aVideo, aAudio));
sl@0
   296
		
sl@0
   297
		if (mp4Err == MP4_OK)
sl@0
   298
			{
sl@0
   299
			// Write audio and video properties to the 3GP file 
sl@0
   300
			err = SetComposeProperties(aVideo, aAudio, aFileFormat, aFlags);
sl@0
   301
			if (err != KErrNone)
sl@0
   302
				{
sl@0
   303
				Complete(); // Ingore the error
sl@0
   304
				}
sl@0
   305
			}
sl@0
   306
		else
sl@0
   307
			{
sl@0
   308
			err = SymbianOSError(mp4Err);
sl@0
   309
			}
sl@0
   310
		}
sl@0
   311
	fileName.Close();
sl@0
   312
	return err;
sl@0
   313
	}
sl@0
   314
sl@0
   315
/**
sl@0
   316
This function initialises the 3GP composer for writing 3GP/3G2/MP4 data into a file.
sl@0
   317
Any combination of one video and one audio type is acceptable.  
sl@0
   318
sl@0
   319
Note: E3GPMetaDataLast will be defaulted in aFlags if file handle is used for the initialisation 
sl@0
   320
of the 3GP composer.
sl@0
   321
sl@0
   322
Note: Ownership of aVideo and aAudio remains with the caller.  Both aVideo and aAudio are ready for 
sl@0
   323
deletion after C3GPCompose::Open returns.
sl@0
   324
sl@0
   325
@param  aFileFormat Specifies the file format in which the data will be created.  Refer to 
sl@0
   326
                    T3GPFileFormatType for supported file format types.
sl@0
   327
@param  aVideo      Specifies the video stream to be used for video data.  The input data given will 
sl@0
   328
                    be inserted into 3GP file headers and is ready to be disposed when 
sl@0
   329
                    C3GPCompose::Open returns. See Video Properties Classes.
sl@0
   330
                    If aVideo is NULL, audio-only file will be composed.
sl@0
   331
@param  aAudio      Specifies the audio stream to be used for audio data.  The input data given will 
sl@0
   332
                    be inserted into 3GP file headers and is ready to be disposed when 
sl@0
   333
                    C3GPCompose::Open returns. See Audio Properties Classes.
sl@0
   334
                    If aAudio is NULL, video-only file will be composed.
sl@0
   335
@param  aFile       File handle of the file to save the data to.  E3GPMetaDataLast needs to be set for 
sl@0
   336
                    aFlags when this is used.
sl@0
   337
@param  aFlags      Optional flags for composing preferences.  Refer to T3GPComposeFlag for supported flags.
sl@0
   338
                    The combined use of flags is acceptable.  For example:
sl@0
   339
                    E3GPLongClip | E3GPMetaDataLast 
sl@0
   340
sl@0
   341
@return KErrNone        if successful. Otherwise, returns one of the system wide error codes.
sl@0
   342
        KErrGeneral     if an error has no specific categorisation;
sl@0
   343
        KErrNoMemory    if an attempt to allocate memory has failed;
sl@0
   344
        KErrArgument    if neither video nor audio stream is specified;         
sl@0
   345
        KErrAccessDenied    if opening file has failed;
sl@0
   346
        KErrInUse   if the composer is currently engaged; C3GPCompose::Complete must be called to 
sl@0
   347
                        finish the current composition before the composer can be re-initialised again.
sl@0
   348
*/
sl@0
   349
sl@0
   350
EXPORT_C TInt C3GPCompose::Open(T3GPFileFormatType aFileFormat,
sl@0
   351
		const T3GPVideoPropertiesBase* aVideo,
sl@0
   352
		const T3GPAudioPropertiesBase* aAudio,
sl@0
   353
		RFile& aFile,
sl@0
   354
		TUint aFlags)
sl@0
   355
	{
sl@0
   356
	TInt err = KErrNone;
sl@0
   357
	if (!iDuplicateFileHandleCreated)
sl@0
   358
		{
sl@0
   359
		iDuplicateFileHandleCreated = ETrue;
sl@0
   360
		iFile.Close();
sl@0
   361
		err = iFile.Duplicate(aFile);
sl@0
   362
		if (err != KErrNone)
sl@0
   363
			{
sl@0
   364
			return err;
sl@0
   365
			}
sl@0
   366
		}
sl@0
   367
sl@0
   368
	return Open(aFileFormat, aVideo, aAudio, iFile, aFlags);
sl@0
   369
	}
sl@0
   370
sl@0
   371
/**
sl@0
   372
This function initialises the 3GP composer for writing 3GP/3G2/MP4 data into a file.
sl@0
   373
Any combination of one video and one audio type is acceptable.  
sl@0
   374
sl@0
   375
Note: E3GPMetaDataLast will be defaulted in aFlags if file handle is used for the initialisation 
sl@0
   376
of the 3GP composer.
sl@0
   377
sl@0
   378
Note: Ownership of aVideo and aAudio remains with the caller.  Both aVideo and aAudio are ready for 
sl@0
   379
deletion after C3GPCompose::Open returns.
sl@0
   380
sl@0
   381
@param	aFileFormat Specifies the file format in which the data will be created.  Refer to 
sl@0
   382
 					T3GPFileFormatType for supported file format types.
sl@0
   383
@param 	aVideo 		Specifies the video stream to be used for video data.  The input data given will 
sl@0
   384
 					be inserted into 3GP file headers and is ready to be disposed when 
sl@0
   385
 					C3GPCompose::Open returns. See Video Properties Classes.
sl@0
   386
 					If aVideo is NULL, audio-only file will be composed.
sl@0
   387
@param 	aAudio 		Specifies the audio stream to be used for audio data.  The input data given will 
sl@0
   388
 					be inserted into 3GP file headers and is ready to be disposed when 
sl@0
   389
 					C3GPCompose::Open returns. See Audio Properties Classes.
sl@0
   390
 					If aAudio is NULL, video-only file will be composed.
sl@0
   391
@param	aFile  		File handle of the file to save the data to.  E3GPMetaDataLast needs to be set for 
sl@0
   392
 					aFlags when this is used.
sl@0
   393
@param	aFlags  	Optional flags for composing preferences.  Refer to T3GPComposeFlag for supported flags.
sl@0
   394
 					The combined use of flags is acceptable.  For example:
sl@0
   395
 					E3GPLongClip | E3GPMetaDataLast 
sl@0
   396
sl@0
   397
@return KErrNone		if successful. Otherwise, returns one of the system wide error codes.
sl@0
   398
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   399
  		KErrNoMemory	if an attempt to allocate memory has failed;
sl@0
   400
  		KErrArgument	if neither video nor audio stream is specified;    		
sl@0
   401
  		KErrAccessDenied	if opening file has failed;
sl@0
   402
  		KErrInUse	if the composer is currently engaged; C3GPCompose::Complete must be called to 
sl@0
   403
  		 		 		finish the current composition before the composer can be re-initialised again.
sl@0
   404
*/
sl@0
   405
EXPORT_C TInt C3GPCompose::Open(T3GPFileFormatType aFileFormat,
sl@0
   406
		const T3GPVideoPropertiesBase* aVideo,
sl@0
   407
		const T3GPAudioPropertiesBase* aAudio,
sl@0
   408
		RFile64& aFile,
sl@0
   409
		TUint aFlags)
sl@0
   410
	{
sl@0
   411
	if (iHandler)
sl@0
   412
		{
sl@0
   413
		return KErrInUse;
sl@0
   414
		}
sl@0
   415
	if (!aVideo && !aAudio)
sl@0
   416
		{
sl@0
   417
		// if neither video nor audio is supplied
sl@0
   418
		return KErrArgument;
sl@0
   419
		}
sl@0
   420
	
sl@0
   421
	TInt driveNumber = EDriveA;
sl@0
   422
	TDriveInfo driveInfo;
sl@0
   423
	TInt err = aFile.Drive(driveNumber, driveInfo);
sl@0
   424
	if (err == KErrNone)
sl@0
   425
		{
sl@0
   426
		MP4Err mp4Err = MP4ComposeOpenFileHandle64(&iHandler, &aFile, static_cast<TDriveNumber>(driveNumber), Mp4Type(aVideo, aAudio));
sl@0
   427
		if (mp4Err == MP4_OK)
sl@0
   428
			{			
sl@0
   429
			// Write audio and video properties to the 3GP file 
sl@0
   430
			err = SetComposeProperties(aVideo, aAudio, aFileFormat, aFlags);
sl@0
   431
			if (err != KErrNone)
sl@0
   432
				{
sl@0
   433
				Complete(); // Ingore the error
sl@0
   434
				}
sl@0
   435
			}
sl@0
   436
		else
sl@0
   437
			{
sl@0
   438
			err = SymbianOSError(mp4Err);
sl@0
   439
			}
sl@0
   440
		}
sl@0
   441
sl@0
   442
	return err;
sl@0
   443
	}
sl@0
   444
sl@0
   445
/**
sl@0
   446
Destructor
sl@0
   447
Deletes all objects and releases all resource owned by this instance.
sl@0
   448
*/
sl@0
   449
EXPORT_C C3GPCompose::~C3GPCompose()
sl@0
   450
	{
sl@0
   451
	Complete(); // Ignore the error
sl@0
   452
	}
sl@0
   453
sl@0
   454
/**
sl@0
   455
This function completes the composing operation. It frees the memory allocated by the library instance 
sl@0
   456
and closes the output file.
sl@0
   457
sl@0
   458
It is necessary to call this function before the output file is guaranteed to be a valid output file 
sl@0
   459
even though the file may exist prior to the call.
sl@0
   460
sl@0
   461
The composer can be reused again after this call, following another call to C3GPCompose::Open to 
sl@0
   462
re-initialise the composer. 
sl@0
   463
sl@0
   464
If C3GPCompose::Complete is called before the composer is initialised, it will be ignored and KErrNone 
sl@0
   465
is returned.
sl@0
   466
sl@0
   467
Although during destruction of C3GPCompose, this function will be automatically called, and no error 
sl@0
   468
code will be returned.  Therefore, when destroying the Composer object that you have used to compose a 
sl@0
   469
file, you should ensure that data is committed to the file by invoking C3GPCompose::Complete before 
sl@0
   470
destroying the Composer object.
sl@0
   471
sl@0
   472
@return KErrNone		if successful. Otherwise, returns one of the system wide error codes.
sl@0
   473
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   474
 		KErrWrite		if metadata could not be written.
sl@0
   475
*/
sl@0
   476
EXPORT_C TInt C3GPCompose::Complete()
sl@0
   477
	{
sl@0
   478
	MP4Err mp4Err = MP4_OK;
sl@0
   479
	if (iHandler)
sl@0
   480
		{
sl@0
   481
		mp4Err = MP4ComposeClose(iHandler);
sl@0
   482
		}
sl@0
   483
	// Always reset the class member data even this function returns error
sl@0
   484
	Reset();
sl@0
   485
	return SymbianOSError(mp4Err);
sl@0
   486
	}
sl@0
   487
sl@0
   488
// Helper function to reset class member data.
sl@0
   489
void C3GPCompose::Reset()
sl@0
   490
	{
sl@0
   491
	iHasVideo = EFalse;
sl@0
   492
	iHasAudio = EFalse;
sl@0
   493
	iHandler = NULL;
sl@0
   494
	iFile.Close();
sl@0
   495
	}
sl@0
   496
sl@0
   497
/**
sl@0
   498
This function writes one video frame to the output file or buffer.
sl@0
   499
sl@0
   500
The frames must be inserted according to their causal sequence.  Because the library doesn't analyze 
sl@0
   501
the video bit stream, frames are inserted into the 3GP file in the same order as they are entered 
sl@0
   502
with this function.  Therefore, the frames will not be retrieved from the resulting 3GP file or 
sl@0
   503
buffer correctly if they are not in proper order.
sl@0
   504
sl@0
   505
A frame inserted with this function call will result in one 3GP sample and one 3GP chunk.
sl@0
   506
sl@0
   507
The current frame's dependency information which is using default values (E3GPDependencyUnknown & 
sl@0
   508
E3GPRedundancyUnknown) is inserted.
sl@0
   509
sl@0
   510
The data is available in the output file only after calling C3GPCompose::Complete. C3GPCompose::Complete 
sl@0
   511
should be called exactly once when all audio and video data has been inserted into the library.
sl@0
   512
sl@0
   513
@param	aBuffer		The descriptor containing the video frame data to be written.
sl@0
   514
@param	aDuration	Duration of video frame in timescale, see T3GPVideoPropertiesBase.
sl@0
   515
@param	aKeyFrame	ETrue to indicate whether this frame is a key frame.  EFalse otherwise.
sl@0
   516
sl@0
   517
@return	KErrNone		if successful. Otherwise, returns one of the system wide error codes.
sl@0
   518
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   519
 		KErrNotSupported if the composer is setup for an audio-only file;
sl@0
   520
 		KErrUnderflow	if the supplied video frame buffer data is empty;
sl@0
   521
 		KErrNotReady	if the composer has not yet been initialised;  See C3GPCompose::Open.
sl@0
   522
*/
sl@0
   523
EXPORT_C TInt C3GPCompose::WriteVideoFrame(const TDesC8& aBuffer, TUint aDuration, TBool aKeyFrame)
sl@0
   524
	{
sl@0
   525
	if (!iHandler)
sl@0
   526
		{
sl@0
   527
		return KErrNotReady;
sl@0
   528
		}
sl@0
   529
	if (aBuffer.Length() <= 0)
sl@0
   530
		{
sl@0
   531
		return KErrUnderflow;
sl@0
   532
		}
sl@0
   533
	if (!iHasVideo)
sl@0
   534
		{
sl@0
   535
		return KErrNotSupported;
sl@0
   536
		}
sl@0
   537
sl@0
   538
	// Insert video frame data
sl@0
   539
	mp4_bool keyFrame = aKeyFrame;
sl@0
   540
	mp4_u32 duration = aDuration;
sl@0
   541
	MP4Err mp4Err = MP4ComposeWriteVideoFrame(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), aBuffer.Length(), duration, keyFrame);
sl@0
   542
	
sl@0
   543
	return SymbianOSError(mp4Err);
sl@0
   544
	}
sl@0
   545
sl@0
   546
/**
sl@0
   547
This function sets the current frame's dependency information to SDTP box and writes one video frame 
sl@0
   548
to the output file.
sl@0
   549
sl@0
   550
The frames must be inserted according to their causal sequence.  Because the library doesn't analyze 
sl@0
   551
the video bit stream, frames are inserted into the 3GP file in the same order as they are entered 
sl@0
   552
with this function.  Therefore, the frames will not be retrieved from the resulting 3GP file or 
sl@0
   553
buffer correctly if they are not in proper order.
sl@0
   554
sl@0
   555
A frame inserted with this function call will result in one 3GP sample and one 3GP chunk.
sl@0
   556
sl@0
   557
The data is available in the output file only after calling C3GPCompose::Complete. C3GPCompose::Complete 
sl@0
   558
should be called exactly once when all audio and video data has been inserted into the library.
sl@0
   559
sl@0
   560
@param	aBuffer		The descriptor containing the video frame data to be written.
sl@0
   561
@param	aDuration	Duration of video frame in timescale, see T3GPVideoPropertiesBase.
sl@0
   562
@param	aKeyFrame	ETrue to indicate whether this frame is a key frame.  EFalse otherwise.
sl@0
   563
@param	aDependencies   This specifies the current frame's dependency information.  
sl@0
   564
					The information will be supplied into the SDTP box.
sl@0
   565
 					See T3GPFrameDependencies.
sl@0
   566
sl@0
   567
@return	KErrNone		if successful. Otherwise, returns one of the system wide error codes.
sl@0
   568
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   569
 		KErrNotSupported if the composer is setup for an audio-only file;
sl@0
   570
 		KErrUnderflow	if the supplied video frame buffer data is empty;
sl@0
   571
 		KErrNotReady	if the composer has not yet been initialised;  See C3GPCompose::Open.
sl@0
   572
*/
sl@0
   573
EXPORT_C TInt C3GPCompose::WriteVideoFrame(const TDesC8& aBuffer, TUint aDuration, TBool aKeyFrame,
sl@0
   574
		const T3GPFrameDependencies& aDependencies)
sl@0
   575
	{
sl@0
   576
	if (!iHandler)
sl@0
   577
		{
sl@0
   578
		return KErrNotReady;
sl@0
   579
		}
sl@0
   580
	if (aBuffer.Length() <= 0)
sl@0
   581
		{
sl@0
   582
		return KErrUnderflow;
sl@0
   583
		}
sl@0
   584
	if (!iHasVideo)
sl@0
   585
		{
sl@0
   586
		return KErrNotSupported;
sl@0
   587
		}
sl@0
   588
sl@0
   589
	// Insert the current frame's dependency information
sl@0
   590
	MP4Err mp4Err = MP4ComposeWriteNextVideoFrameDependencies(iHandler, aDependencies.iDependsOn,
sl@0
   591
			aDependencies.iIsDependedOn, aDependencies.iHasRedundancy);
sl@0
   592
sl@0
   593
	if (mp4Err == MP4_OK)
sl@0
   594
		{
sl@0
   595
		// Insert video frame data
sl@0
   596
		mp4_bool keyFrame = aKeyFrame;
sl@0
   597
		mp4_u32 duration = aDuration;
sl@0
   598
		mp4Err = MP4ComposeWriteVideoFrame(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), 
sl@0
   599
				aBuffer.Length(), duration, keyFrame);
sl@0
   600
		}
sl@0
   601
sl@0
   602
	return SymbianOSError(mp4Err);
sl@0
   603
	}
sl@0
   604
sl@0
   605
/**
sl@0
   606
This function writes audio frames into the output file or buffer.  The data is available in the 
sl@0
   607
3GP output file only after calling C3GPCompose::Complete.  C3GPCompose::Complete should be called exactly 
sl@0
   608
once when all audio and video data has been inserted into the library.
sl@0
   609
sl@0
   610
For MPEG-4 audio:
sl@0
   611
This function writes one MPEG audio frame to the 3GP file. 
sl@0
   612
sl@0
   613
For other audio types:
sl@0
   614
This function writes a number of audio frames to the 3GP file specified during composer setup 
sl@0
   615
in the input parameter aAudio when calling C3GPCompose::Open.  All audio frames inserted with 
sl@0
   616
one function call will be placed inside one sample in the resulting file.
sl@0
   617
sl@0
   618
Note: Only the last call can have a different number of frames if the number is less than 
sl@0
   619
the number of frames per sample specified during composer setup.
sl@0
   620
sl@0
   621
@see T3GPAudioPropertiesAmr
sl@0
   622
@see T3GPAudioPropertiesQcelp  		
sl@0
   623
sl@0
   624
@param	aBuffer			The descriptor containing the audio data to be written.
sl@0
   625
@param	aDuration		Duration of audio frames in timescale, see T3GPAudioPropertiesBase
sl@0
   626
sl@0
   627
@return	KErrNone		if successful.  Otherwise, returns one of the system wide error codes.
sl@0
   628
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   629
 		KErrNotSupported if the composer is setup for a video-only file;
sl@0
   630
 		KErrUnderflow	if the supplied audio frames buffer data is empty;
sl@0
   631
 		KErrNotReady	if the composer has not yet been initialised;  See C3GPCompose::Open.
sl@0
   632
*/
sl@0
   633
EXPORT_C TInt C3GPCompose::WriteAudioFrames(const TDesC8& aBuffer, TUint aDuration)
sl@0
   634
	{
sl@0
   635
	if (!iHandler)
sl@0
   636
		{
sl@0
   637
		return KErrNotReady;
sl@0
   638
		}
sl@0
   639
	if (aBuffer.Length() <= 0)
sl@0
   640
		{
sl@0
   641
		return KErrUnderflow;
sl@0
   642
		}
sl@0
   643
	if (!iHasAudio)
sl@0
   644
		{
sl@0
   645
		return KErrNotSupported;
sl@0
   646
		}
sl@0
   647
sl@0
   648
	mp4_u32 duration = aDuration;
sl@0
   649
    // use 0 for the number of frames since it is being ignored within the mp4 library implementation
sl@0
   650
	MP4Err mp4Err = MP4ComposeWriteAudioFrames(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), 
sl@0
   651
			aBuffer.Length(), 0, duration);
sl@0
   652
	
sl@0
   653
	return SymbianOSError(mp4Err);
sl@0
   654
	}
sl@0
   655
sl@0
   656
/**
sl@0
   657
Writes a buffer containing whole atom to inside of user data atom (UDTA) defined in aLocation.
sl@0
   658
sl@0
   659
The buffer should contain an atom of structure that conforms to the definition of a "full box" 
sl@0
   660
as specified in ISO/IEC 14496-12:2003: "Information technology – Coding of audio-visual objects
sl@0
   661
 – Part 12: ISO base media file format."
sl@0
   662
 
sl@0
   663
For more information on user data atoms, see Section 8 – Asset Information of "3GPP TS 26.244 
sl@0
   664
version 6.1.0 – 3GP file format (Rel 6)."
sl@0
   665
sl@0
   666
@param	aLocation	Specifies the location of user information to be written.  Refer to 
sl@0
   667
 					T3GPUdtaLocation for possible values.
sl@0
   668
@param	aBuffer		The descriptor containing the user information to write into file.
sl@0
   669
sl@0
   670
@return	KErrNone		if successful.  Otherwise, returns one of the system wide error codes.
sl@0
   671
 		KErrGeneral		if an error has no specific categorisation;
sl@0
   672
 		KErrArgument	if asked aLocation is invalid;
sl@0
   673
 		KErrUnderflow	if the supplied buffer data is empty;
sl@0
   674
 		KErrNotSupported	if specify video track user data but no video type is specified, 
sl@0
   675
 						or specify audio track user data but no audio type is specified
sl@0
   676
 		KErrNoMemory	if an attempt to allocate memory has failed;
sl@0
   677
 		KErrNotReady	if the composer has not yet been initialised;  See C3GPCompose::Open.
sl@0
   678
 		
sl@0
   679
@panic	C3GPCompose	KErrArgument if the location of user information is not of T3GPUdtaLocation. 
sl@0
   680
*/
sl@0
   681
EXPORT_C TInt C3GPCompose::SetUserData(T3GPUdtaLocation aLocation, const TDesC8& aBuffer)
sl@0
   682
	{
sl@0
   683
	if (!iHandler)
sl@0
   684
		{
sl@0
   685
		return KErrNotReady;
sl@0
   686
		}
sl@0
   687
	if (aBuffer.Length() <= 0)
sl@0
   688
		{
sl@0
   689
		return KErrUnderflow;
sl@0
   690
		}
sl@0
   691
	if ((!iHasAudio && aLocation == E3GPUdtaAudioTrak) || (!iHasVideo && aLocation == E3GPUdtaVideoTrak))
sl@0
   692
		{
sl@0
   693
		return KErrNotSupported;
sl@0
   694
		}
sl@0
   695
	
sl@0
   696
	mp4_u8 location;
sl@0
   697
	switch (aLocation)
sl@0
   698
		{
sl@0
   699
		case (E3GPUdtaMoov):
sl@0
   700
			location = MP4_UDTA_MOOV;
sl@0
   701
		break;
sl@0
   702
		case (E3GPUdtaVideoTrak):
sl@0
   703
			location = MP4_UDTA_VIDEOTRAK;
sl@0
   704
		break;
sl@0
   705
		case (E3GPUdtaAudioTrak):
sl@0
   706
			location = MP4_UDTA_AUDIOTRAK;
sl@0
   707
		break;
sl@0
   708
		default:
sl@0
   709
			Panic(KErrArgument);
sl@0
   710
		break;
sl@0
   711
		}
sl@0
   712
sl@0
   713
	mp4_u32 bufferSize = aBuffer.Length();
sl@0
   714
	MP4Err mp4Err = MP4ComposeSetUserDataAtom(iHandler, location, const_cast<mp4_u8*>(aBuffer.Ptr()), bufferSize);
sl@0
   715
	return SymbianOSError(mp4Err);
sl@0
   716
	}
sl@0
   717
sl@0
   718
// Helper function to convert 3GP/MP4 library specific error codes to system wide error codes
sl@0
   719
TInt C3GPCompose::SymbianOSError(MP4Err aError)
sl@0
   720
	{
sl@0
   721
	TInt error = KErrNone;
sl@0
   722
sl@0
   723
	switch (aError)
sl@0
   724
		{
sl@0
   725
		case (MP4_OK):
sl@0
   726
		break;
sl@0
   727
		case (MP4_ERROR):
sl@0
   728
			error = KErrGeneral;
sl@0
   729
		break;
sl@0
   730
		case (MP4_OUT_OF_MEMORY):
sl@0
   731
			error = KErrNoMemory;
sl@0
   732
		break;
sl@0
   733
		case (MP4_FILE_ERROR):
sl@0
   734
			error = KErrAccessDenied;
sl@0
   735
		break;
sl@0
   736
		case (MP4_INVALID_TYPE):
sl@0
   737
			error = KErrArgument;
sl@0
   738
		break;
sl@0
   739
		case (MP4_METADATA_ERROR):
sl@0
   740
			error = KErrWrite;
sl@0
   741
		break;
sl@0
   742
		default:
sl@0
   743
			Panic(KErrArgument);
sl@0
   744
		}
sl@0
   745
	return error;
sl@0
   746
	}
sl@0
   747
sl@0
   748
// Helper function to map 3GP enum type to MP4 audio and video type
sl@0
   749
mp4_u32 C3GPCompose::Mp4Type(const T3GPVideoPropertiesBase* aVideo, const T3GPAudioPropertiesBase* aAudio)
sl@0
   750
	{
sl@0
   751
	mp4_u32 videoType = MP4_TYPE_NONE;
sl@0
   752
	mp4_u32 audioType = MP4_TYPE_NONE;
sl@0
   753
	
sl@0
   754
	if (aVideo)
sl@0
   755
		{
sl@0
   756
		iHasVideo = ETrue;
sl@0
   757
		switch (aVideo->iType)
sl@0
   758
			{
sl@0
   759
			case (E3GPMpeg4Video):
sl@0
   760
				videoType = MP4_TYPE_MPEG4_VIDEO;
sl@0
   761
			break;
sl@0
   762
			case (E3GPH263Profile0):
sl@0
   763
				videoType = MP4_TYPE_H263_PROFILE_0;
sl@0
   764
			break;
sl@0
   765
			case (E3GPH263Profile3):
sl@0
   766
				videoType = MP4_TYPE_H263_PROFILE_3;
sl@0
   767
			break;
sl@0
   768
			
sl@0
   769
			/*
sl@0
   770
			 * NOTE: The underlying 3GP library does
sl@0
   771
			 * not differentiate between the various AVC
sl@0
   772
			 * profiles when composing.
sl@0
   773
			 * 
sl@0
   774
			 * In all cases it will simply copy the data
sl@0
   775
			 * from the iDecoderSpecificInfo member of
sl@0
   776
			 * T3GPVideoPropertiesAvc into the 'avcC' atom.
sl@0
   777
			 * It does not do any checking of that data, so
sl@0
   778
			 * it is the API user's responsibility to ensure
sl@0
   779
			 * that it contains a valid AVCDecoderConfigurationRecord
sl@0
   780
			 * with the correct AVC profile and level.
sl@0
   781
			 * 
sl@0
   782
			 * An interesting side-effect of this is that you can
sl@0
   783
			 * compose AVC data with arbitrary profiles even if they
sl@0
   784
			 * are not "supported" by this API. For example, as long
sl@0
   785
			 * as the AVCDecoderConfigurationRecord says there is
sl@0
   786
			 * High 10 profile data and the AVC data is of that profile
sl@0
   787
			 * then you will still end up with a valid file.
sl@0
   788
			 */
sl@0
   789
			case (E3GPAvcProfileBaseline):
sl@0
   790
				videoType = MP4_TYPE_AVC_PROFILE_BASELINE;
sl@0
   791
			break;
sl@0
   792
            case (E3GPAvcProfileMain):
sl@0
   793
                videoType = MP4_TYPE_AVC_PROFILE_MAIN;
sl@0
   794
            break;
sl@0
   795
            case (E3GPAvcProfileExtended):
sl@0
   796
                videoType = MP4_TYPE_AVC_PROFILE_EXTENDED;
sl@0
   797
            break;
sl@0
   798
            case (E3GPAvcProfileHigh):
sl@0
   799
                videoType = MP4_TYPE_AVC_PROFILE_HIGH;
sl@0
   800
            break;
sl@0
   801
			default:
sl@0
   802
				Panic(KErrArgument);
sl@0
   803
			}
sl@0
   804
		}
sl@0
   805
sl@0
   806
	if(aAudio)
sl@0
   807
		{
sl@0
   808
		iHasAudio = ETrue;
sl@0
   809
		switch (aAudio->iType)
sl@0
   810
			{
sl@0
   811
			case (E3GPMpeg4Audio):
sl@0
   812
				audioType = MP4_TYPE_MPEG4_AUDIO;
sl@0
   813
			break;
sl@0
   814
			case (E3GPAmrNB):
sl@0
   815
				audioType = MP4_TYPE_AMR_NB;
sl@0
   816
			break;
sl@0
   817
			case (E3GPAmrWB):
sl@0
   818
				audioType = MP4_TYPE_AMR_WB;
sl@0
   819
			break;
sl@0
   820
			case (E3GPQcelp13K):
sl@0
   821
				audioType = MP4_TYPE_QCELP_13K;
sl@0
   822
			break;
sl@0
   823
			default:
sl@0
   824
				Panic(KErrArgument);
sl@0
   825
			}
sl@0
   826
		}
sl@0
   827
	return (videoType | audioType);
sl@0
   828
	}
sl@0
   829
	
sl@0
   830
// Helper function to set compose properties
sl@0
   831
TInt C3GPCompose::SetComposeProperties(const T3GPVideoPropertiesBase* aVideo,
sl@0
   832
		const T3GPAudioPropertiesBase* aAudio, T3GPFileFormatType aFileFormat, TUint aFlag)
sl@0
   833
	{
sl@0
   834
	mp4_u32 writeBufferSize = iMediaWriteBufferSize;
sl@0
   835
	mp4_u32 writeBufferMaxCount = iWriteBufferMaxCount;
sl@0
   836
	MP4Err mp4Err = MP4SetCustomFileBufferSizes(iHandler, writeBufferSize, writeBufferMaxCount, 0);
sl@0
   837
	if ( mp4Err != MP4_OK)
sl@0
   838
		{
sl@0
   839
		return SymbianOSError(mp4Err);
sl@0
   840
		}
sl@0
   841
	
sl@0
   842
	// Set compose flag before other MP4Compose functions
sl@0
   843
	TInt err = SetComposeFlag(aFileFormat, aFlag);
sl@0
   844
	if (err != KErrNone)
sl@0
   845
		{
sl@0
   846
		return err;
sl@0
   847
		}
sl@0
   848
	
sl@0
   849
	if (aVideo)
sl@0
   850
		{
sl@0
   851
		switch (aVideo->iType)
sl@0
   852
			{
sl@0
   853
			case (E3GPMpeg4Video):
sl@0
   854
				err = SetMPeg4VideoProperties(aVideo);
sl@0
   855
			break;
sl@0
   856
			case (E3GPAvcProfileBaseline):
sl@0
   857
            case (E3GPAvcProfileMain):
sl@0
   858
            case (E3GPAvcProfileExtended):
sl@0
   859
            case (E3GPAvcProfileHigh):
sl@0
   860
				err = SetAvcVideoProperties(aVideo);
sl@0
   861
			break;
sl@0
   862
			case (E3GPH263Profile0):
sl@0
   863
			case (E3GPH263Profile3):
sl@0
   864
				err = SetH263VideoProperties(aVideo);
sl@0
   865
			break;
sl@0
   866
			default:
sl@0
   867
				Panic(KErrArgument);
sl@0
   868
			}
sl@0
   869
		}
sl@0
   870
	if (err != KErrNone)
sl@0
   871
		{
sl@0
   872
		return err;
sl@0
   873
		}
sl@0
   874
sl@0
   875
	if (aAudio)
sl@0
   876
		{
sl@0
   877
		switch (aAudio->iType)
sl@0
   878
			{
sl@0
   879
			case (E3GPMpeg4Audio):
sl@0
   880
				err = SetMpeg4AudioProperties(aAudio);
sl@0
   881
			break;
sl@0
   882
			case (E3GPQcelp13K):
sl@0
   883
				err = SetQcelpAudioProperties(aAudio);
sl@0
   884
			break;
sl@0
   885
			case (E3GPAmrNB):
sl@0
   886
			case (E3GPAmrWB):
sl@0
   887
				err = SetAmrAudioProperties(aAudio);
sl@0
   888
			break;
sl@0
   889
			default:
sl@0
   890
				Panic(KErrArgument);
sl@0
   891
			}
sl@0
   892
		}
sl@0
   893
	return err;
sl@0
   894
	}
sl@0
   895
sl@0
   896
// Inform the 3GP library about the MPeg4 video data
sl@0
   897
TInt C3GPCompose::SetMPeg4VideoProperties(const T3GPVideoPropertiesBase* aVideo)
sl@0
   898
	{
sl@0
   899
	const T3GPVideoPropertiesMpeg4Video* mpeg4Video = static_cast<const T3GPVideoPropertiesMpeg4Video*>(aVideo);
sl@0
   900
sl@0
   901
	MP4Err err = MP4ComposeWriteVideoDecoderSpecificInfo(iHandler, const_cast<mp4_u8*>(mpeg4Video->iDecoderSpecificInfo.Ptr()), 
sl@0
   902
			mpeg4Video->iDecoderSpecificInfo.Length());
sl@0
   903
sl@0
   904
	if ( err == MP4_OK)
sl@0
   905
		{
sl@0
   906
		err = MP4ComposeAddVideoDescription(iHandler, mpeg4Video->iTimescale,
sl@0
   907
				mpeg4Video->iSize.iWidth, mpeg4Video->iSize.iHeight,
sl@0
   908
				mpeg4Video->iMaxBitRate, mpeg4Video->iAvgBitRate);
sl@0
   909
		}
sl@0
   910
sl@0
   911
	return SymbianOSError(err);
sl@0
   912
	}
sl@0
   913
sl@0
   914
// Inform the 3GP library about the AVC video data
sl@0
   915
TInt C3GPCompose::SetAvcVideoProperties(const T3GPVideoPropertiesBase* aVideo)
sl@0
   916
	{
sl@0
   917
	const T3GPVideoPropertiesAvc* avcVideo = static_cast<const T3GPVideoPropertiesAvc*>(aVideo);
sl@0
   918
sl@0
   919
	MP4Err err = MP4ComposeWriteVideoDecoderSpecificInfo(iHandler, const_cast<mp4_u8*>(avcVideo->iDecoderSpecificInfo.Ptr()), 
sl@0
   920
			avcVideo->iDecoderSpecificInfo.Length ());
sl@0
   921
sl@0
   922
	if ( err == MP4_OK)
sl@0
   923
		{
sl@0
   924
		// aMaxBitRate and aAvgBitRate are MPEG-4 video specific values.  Set 0 for them
sl@0
   925
		err = MP4ComposeAddVideoDescription(iHandler, avcVideo->iTimescale,
sl@0
   926
				avcVideo->iSize.iWidth, avcVideo->iSize.iHeight, 0, 0);
sl@0
   927
		}
sl@0
   928
sl@0
   929
	return SymbianOSError(err);
sl@0
   930
	}
sl@0
   931
sl@0
   932
// Inform the 3GP library about the H263 video data
sl@0
   933
TInt C3GPCompose::SetH263VideoProperties(const T3GPVideoPropertiesBase* aVideo)
sl@0
   934
	{
sl@0
   935
	// aMaxBitRate and aAvgBitRate are MPEG-4 video specific values.  Set 0 for H263 video
sl@0
   936
	MP4Err err = MP4ComposeAddVideoDescription(iHandler, aVideo->iTimescale,
sl@0
   937
			aVideo->iSize.iWidth, aVideo->iSize.iHeight, 0, 0);
sl@0
   938
sl@0
   939
	if ( err == MP4_OK)
sl@0
   940
		{
sl@0
   941
		const T3GPVideoPropertiesH263* h263Video = static_cast<const T3GPVideoPropertiesH263*>(aVideo);
sl@0
   942
		TVideoClipProperties properties;
sl@0
   943
		properties.iH263Level = h263Video->iVideoLevel;
sl@0
   944
		err = MP4ComposeSetVideoClipProperties(iHandler, properties);
sl@0
   945
		}
sl@0
   946
sl@0
   947
	return SymbianOSError(err);
sl@0
   948
	}
sl@0
   949
sl@0
   950
// Inform the 3GP library about the MPeg4 audio data
sl@0
   951
TInt C3GPCompose::SetMpeg4AudioProperties(const T3GPAudioPropertiesBase* aAudio)
sl@0
   952
	{
sl@0
   953
	const T3GPAudioPropertiesMpeg4Audio* mpeg4Audio = static_cast<const T3GPAudioPropertiesMpeg4Audio*>(aAudio);
sl@0
   954
sl@0
   955
	MP4Err err = MP4ComposeWriteAudioDecoderSpecificInfo(iHandler, const_cast<mp4_u8*>(mpeg4Audio->iDecoderSpecificInfo.Ptr()), 
sl@0
   956
			mpeg4Audio->iDecoderSpecificInfo.Length ());
sl@0
   957
sl@0
   958
	if ( err == MP4_OK)
sl@0
   959
		{
sl@0
   960
		//modeSet is needed only for AMR audio. Set it to 0 for Mpeg4 audio.
sl@0
   961
		err = MP4ComposeAddAudioDescription(iHandler, mpeg4Audio->iTimescale, mpeg4Audio->iFramesPerSample, 0);
sl@0
   962
		}
sl@0
   963
sl@0
   964
	return SymbianOSError(err);
sl@0
   965
	}
sl@0
   966
sl@0
   967
// Inform the 3GP library about the Amr audio data
sl@0
   968
TInt C3GPCompose::SetAmrAudioProperties(const T3GPAudioPropertiesBase* aAudio)
sl@0
   969
	{
sl@0
   970
	const T3GPAudioPropertiesAmr* amrAudio = static_cast<const T3GPAudioPropertiesAmr*>(aAudio);
sl@0
   971
	//modeSet is needed only for AMR audio. 
sl@0
   972
	MP4Err err = MP4ComposeAddAudioDescription(iHandler, amrAudio->iTimescale,
sl@0
   973
			amrAudio->iFramesPerSample, amrAudio->iModeSet);
sl@0
   974
	return SymbianOSError(err);
sl@0
   975
	}
sl@0
   976
sl@0
   977
// Sets the storage mode of storing 13K QCELP data in a 3G2 file
sl@0
   978
TInt C3GPCompose::SetQcelpAudioProperties(const T3GPAudioPropertiesBase* aAudio)
sl@0
   979
	{
sl@0
   980
	const T3GPAudioPropertiesQcelp* qcelpAudio = static_cast<const T3GPAudioPropertiesQcelp*>(aAudio);
sl@0
   981
	MP4Err err = MP4ComposeSetQCELPStorageMode(iHandler, qcelpAudio->iMode);
sl@0
   982
	if ( err == MP4_OK)
sl@0
   983
		{
sl@0
   984
		if ( qcelpAudio->iMode == E3GPMP4AudioDescriptionBox)
sl@0
   985
			{
sl@0
   986
			err = MP4ComposeWriteAudioDecoderSpecificInfo(iHandler, const_cast<mp4_u8*>(qcelpAudio->iDecoderSpecificInfo.Ptr()), qcelpAudio->iDecoderSpecificInfo.Length ());
sl@0
   987
			}
sl@0
   988
		if ( err == MP4_OK)
sl@0
   989
			{
sl@0
   990
			//modeSet is needed only for AMR audio. Set it to 0 for Qcelp audio.
sl@0
   991
			err = MP4ComposeAddAudioDescription(iHandler, qcelpAudio->iTimescale, qcelpAudio->iFramesPerSample, 0);
sl@0
   992
			}
sl@0
   993
		}
sl@0
   994
sl@0
   995
	return SymbianOSError(err);
sl@0
   996
	}
sl@0
   997
sl@0
   998
// Set compose flag
sl@0
   999
TInt C3GPCompose::SetComposeFlag(T3GPFileFormatType aFileFormat, TUint aFlag)
sl@0
  1000
	{
sl@0
  1001
	mp4_u32 fileFormat = 0;
sl@0
  1002
	switch (aFileFormat)
sl@0
  1003
		{
sl@0
  1004
		case (E3GPMP4):
sl@0
  1005
			fileFormat = MP4_FLAG_GENERATE_MP4;
sl@0
  1006
		break;
sl@0
  1007
		case (E3GP3G2):
sl@0
  1008
			fileFormat = MP4_FLAG_GENERATE_3G2;
sl@0
  1009
		break;
sl@0
  1010
		case (E3GP3GP):
sl@0
  1011
			fileFormat = MP4_FLAG_NONE;
sl@0
  1012
		break;
sl@0
  1013
		default:
sl@0
  1014
			Panic(KErrArgument);
sl@0
  1015
		}
sl@0
  1016
sl@0
  1017
	MP4Err err = MP4ComposeSetFlags(iHandler, aFlag | fileFormat);
sl@0
  1018
	return SymbianOSError(err);
sl@0
  1019
	}
sl@0
  1020
sl@0
  1021
sl@0
  1022
void C3GPCompose::Panic(TInt aPanic)
sl@0
  1023
// Panic client
sl@0
  1024
	{
sl@0
  1025
	User::Panic(K3GPComposePanicName, aPanic);
sl@0
  1026
	}