mmplugins/lib3gp/wrapper/src/c3gpparse.cpp
changeset 0 40261b775718
child 11 d5f04de580b7
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <c3gplibrary.h>
       
    17 
       
    18 /**
       
    19 Creates an instance of a 3GP Parser for reading 3GP/3G2/MP4 data using default buffer size.
       
    20 
       
    21 The default value for read buffer size is 8k. 
       
    22 
       
    23 @return A pointer to the newly created 3gp parse object. 
       
    24 
       
    25 @leave	KErrNoMemory	Out of memory.
       
    26 */
       
    27 EXPORT_C C3GPParse* C3GPParse::NewL()
       
    28 	{
       
    29 	C3GPParse* self = new (ELeave) C3GPParse();
       
    30 	return self;
       
    31 	}
       
    32 
       
    33 /**
       
    34 Creates an instance of a 3GP Parser for reading 3GP/3G2/MP4 data, and sets the 
       
    35 internal file read buffer size.  
       
    36 
       
    37 @param	aReadBufferSize	Size of file read buffer.
       
    38 
       
    39 @return A pointer to the newly created 3gp parse object. 
       
    40 
       
    41 @leave	KErrNoMemory	Out of memory.
       
    42 @leave	KErrGeneral		General error.
       
    43 
       
    44 @panic	C3GPParse	KErrArgument	if size of file read buffer is not greater than 0.
       
    45 */
       
    46 EXPORT_C C3GPParse* C3GPParse::NewL(TInt aReadBufferSize)
       
    47 	{
       
    48 	__ASSERT_ALWAYS((aReadBufferSize > 0), Panic(KErrArgument));
       
    49 	C3GPParse* self = new (ELeave) C3GPParse(aReadBufferSize);
       
    50 	return self;
       
    51 	}
       
    52 
       
    53 // First phase constructor
       
    54 C3GPParse::C3GPParse(TInt aReadBufferSize) : 
       
    55 		iReadBufferSize(aReadBufferSize),
       
    56 		iDuplicateFileHandleCreated(EFalse),
       
    57 		iVideoType(E3GPNoVideo),
       
    58 		iAudioType(E3GPNoAudio)
       
    59 	{
       
    60 	}
       
    61 
       
    62 /**
       
    63 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a buffer and expects data 
       
    64 to be inserted through subsequent calls to C3GPParse::InsertData.  
       
    65 
       
    66 @see C3GPParse::InsertData
       
    67 
       
    68 @return	KErrNone 		if successful. Otherwise, returns one of the system wide error codes.
       
    69 		KErrGeneral		if an error has no specific categorisation;
       
    70 		KErrNoMemory	if an attempt to allocate memory has failed;
       
    71 		KErrInUse		if the parser is currently engaged; C3GPParse::Complete must be called to 
       
    72 						finish the parsing activities before the parser can be re-initialised again.
       
    73 */	
       
    74 EXPORT_C TInt C3GPParse::Open()
       
    75 	{
       
    76 	if (iHandler)
       
    77 		{
       
    78 		return KErrInUse;
       
    79 		}
       
    80 	
       
    81 	return SymbianOSError(MP4ParseOpen(&iHandler, NULL));
       
    82 	}
       
    83 
       
    84 /**
       
    85 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a file.
       
    86 
       
    87 @param	aFilename	A full path name of the file containing the data. 
       
    88 
       
    89 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
    90 		KErrGeneral		if an error has no specific categorisation;
       
    91 		KErrNoMemory	if an attempt to allocate memory has failed;
       
    92 		KErrAccessDenied	if opening file has failed;
       
    93 		KErrUnderflow	if the file name length is not greater than 0;
       
    94 		KErrInUse		if the parser is currently engaged;  C3GPParse::Complete must be called to 
       
    95 						finish the parsing activities before the parser can be re-initialised again.
       
    96 */	
       
    97 EXPORT_C TInt C3GPParse::Open(const TDesC& aFilename)
       
    98 	{
       
    99 	if (iHandler)
       
   100 		{
       
   101 		return KErrInUse;
       
   102 		}
       
   103 	if (aFilename.Length() <= 0)
       
   104 		{
       
   105 		return KErrUnderflow;
       
   106 		}
       
   107 	
       
   108 	// Create a zero terminated version of the file name
       
   109 	RBuf fileName;	
       
   110 	TInt err = fileName.Create(aFilename.Length() + 1);
       
   111 	if (err == KErrNone)
       
   112 		{
       
   113 		fileName.Copy(aFilename);
       
   114 		mp4_u16* mp4FileName = const_cast<mp4_u16*>(fileName.PtrZ());
       
   115 		MP4Err mp4Err = MP4ParseOpen(&iHandler, reinterpret_cast<MP4FileName>(mp4FileName));
       
   116 		
       
   117 		if (mp4Err == MP4_OK)
       
   118 			{
       
   119 			// Set composing related values to 0.
       
   120 			mp4Err = MP4SetCustomFileBufferSizes(iHandler, 0, 0, iReadBufferSize);
       
   121 			if (mp4Err != MP4_OK)
       
   122 				{
       
   123 				// Ignore the error
       
   124 				Complete();
       
   125 				}
       
   126 			}
       
   127 		err = SymbianOSError(mp4Err);
       
   128 		}
       
   129 	fileName.Close();
       
   130 	return err;
       
   131 	}
       
   132 
       
   133 /**
       
   134 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a file.
       
   135 
       
   136 @param  aFile   File handle of the file containing the data.  It is expected to be a valid file handle, 
       
   137                 opened and will be closed outside of the library.
       
   138 
       
   139 @return KErrNone        if successful.  Otherwise, returns one of the system wide error codes.
       
   140         KErrNoMemory    if an attempt to allocate memory has failed;
       
   141         KErrInUse       if the parser is currently engaged;  C3GPParse::Complete must be called to 
       
   142                         finish the parsing activities before the parser can be re-initialised again.
       
   143 */
       
   144 EXPORT_C TInt C3GPParse::Open(const RFile& aFile)
       
   145 	{
       
   146 	TInt err = KErrNone;
       
   147 	if (!iDuplicateFileHandleCreated)
       
   148 		{
       
   149 		iDuplicateFileHandleCreated = ETrue;
       
   150 		iFile.Close();
       
   151 		err = iFile.Duplicate(aFile);
       
   152 		if (err != KErrNone)
       
   153 			{
       
   154 			return err;
       
   155 			}
       
   156 		}
       
   157 
       
   158 	return Open(iFile);
       
   159 	}
       
   160 /**
       
   161 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a file.
       
   162 
       
   163 @param	aFile	File handle of the file containing the data.  It is expected to be a valid file handle, 
       
   164 				opened and will be closed outside of the library.
       
   165 
       
   166 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   167 		KErrNoMemory	if an attempt to allocate memory has failed;
       
   168 		KErrInUse		if the parser is currently engaged;  C3GPParse::Complete must be called to 
       
   169 						finish the parsing activities before the parser can be re-initialised again.
       
   170 */
       
   171 EXPORT_C TInt C3GPParse::Open(const RFile64& aFile)
       
   172 	{
       
   173 	if (iHandler)
       
   174 		{
       
   175 		return KErrInUse;
       
   176 		}
       
   177 	
       
   178 	const RFile64* file = &aFile;
       
   179 	MP4Err mp4Err = MP4ParseOpenFileHandle64(&iHandler, (const_cast<RFile64*>(file)));
       
   180 	if (mp4Err == MP4_OK)
       
   181 		{
       
   182 		// Set composing related values to 0.
       
   183 		mp4Err = MP4SetCustomFileBufferSizes(iHandler, 0, 0, iReadBufferSize);
       
   184 		if (mp4Err != MP4_OK)
       
   185 			{
       
   186 			// Ignore the error
       
   187 			Complete();
       
   188 			}
       
   189 		}
       
   190 
       
   191 	return SymbianOSError(mp4Err);
       
   192 	}
       
   193 
       
   194 /**
       
   195 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a CAF object.
       
   196 
       
   197 @param	aData	A CData object pointing to a CAF object.  It is expected to be opened and will be 
       
   198 				closed outside of the library.
       
   199 
       
   200 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   201 		KErrNoMemory	if an attempt to allocate memory has failed;
       
   202 		KErrInUse		if the parser is currently engaged;  C3GPParse::Complete must be called to 
       
   203 						finish the parsing activities before the parser can be re-initialised again.
       
   204 */
       
   205 EXPORT_C TInt C3GPParse::Open(const ContentAccess::CData& aData)
       
   206 	{
       
   207 	if (iHandler)
       
   208 		{
       
   209 		return KErrInUse;
       
   210 		}
       
   211 	
       
   212 	MP4Err mp4Err = MP4ParseOpenCAF(&iHandler, const_cast<ContentAccess::CData*>(&aData));
       
   213 
       
   214 	if (mp4Err  == MP4_OK)
       
   215 		{
       
   216 		// Set composing related values to 0.
       
   217 		mp4Err = MP4SetCustomFileBufferSizes(iHandler, 0, 0, iReadBufferSize);
       
   218 		if (mp4Err != MP4_OK)
       
   219 			{
       
   220 			// Ignore the error
       
   221 			Complete();
       
   222 			}
       
   223 		}
       
   224 	
       
   225 	return SymbianOSError(mp4Err);
       
   226 	}
       
   227 
       
   228 /**
       
   229 Destructor. Deletes all objects.
       
   230 */
       
   231 EXPORT_C C3GPParse::~C3GPParse()
       
   232 	{
       
   233 	Complete(); // Ignore the error
       
   234 	}
       
   235 
       
   236 /**
       
   237 This function completes the parsing operation.
       
   238 
       
   239 If C3GPParse::Complete is called before the parse is initialised, it will be ignored and KErrNone is 
       
   240 returned.
       
   241 
       
   242 The parser can be reused again after this call, following another call to C3GPParse::Open to 
       
   243 re-initialise the parser. 
       
   244 
       
   245 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   246 		KErrGeneral		if an error has no specific categorisation;
       
   247 */
       
   248 EXPORT_C TInt C3GPParse::Complete()
       
   249 	{
       
   250 	MP4Err mp4Err = MP4_OK;
       
   251 	if (iHandler)
       
   252 		{
       
   253 		mp4Err = MP4ParseClose(iHandler);
       
   254 		}
       
   255 		
       
   256 	if (iAsyncReadBuffer)
       
   257 		{
       
   258 		CancelReadFrame();
       
   259 		}
       
   260 	
       
   261 	// Always reset the class member data even MP4ParseClose returns error
       
   262 	Reset();
       
   263 	return SymbianOSError(mp4Err);
       
   264 	}
       
   265 
       
   266 // Helper function to reset class member data.
       
   267 void C3GPParse::Reset()
       
   268 	{
       
   269 	iVideoType = E3GPNoVideo;
       
   270 	iAudioType = E3GPNoAudio;
       
   271 	iAsyncReadBuffer = NULL;
       
   272 	iCallback = NULL; // Parse doesn't own the callback. Set it to NULL.
       
   273 	iAudioAvgBitRate = 0;
       
   274 	iStreamAvgBitRate = 0;
       
   275 	iVideoPropertiesSaved = EFalse;
       
   276 	iAudioPropertiesSaved = EFalse;
       
   277 	iStreamPropertiesSaved = EFalse;
       
   278 	iVideoError = KErrNone;
       
   279 	iAudioError = KErrNone;
       
   280 	iStreamError = KErrNone;
       
   281 	iHandler = NULL;
       
   282 	iDuplicateFileHandleCreated = EFalse;
       
   283 	iFile.Close();
       
   284 	}
       
   285 
       
   286 /**
       
   287 This function inserts MP4/3GP/3G2 data into the parser.
       
   288 
       
   289 It is only necessary to call this function if no parameter has been supplied when 
       
   290 C3GPParse::Open is called.  Several functions can return KErr3gpLibMoreDataRequired if the library 
       
   291 does not have enough data to return the information that the caller requests. In this case, more data 
       
   292 needs to be inserted to the library before calling those functions again.
       
   293 
       
   294 This function makes a copy of the data inserted into the library so the caller can use the input buffer 
       
   295 for other purposes. If the function returns KErrNoMemory, the buffer contents have not been copied into 
       
   296 the library and the caller needs to reduce the buffer content before calling again.
       
   297 
       
   298 If an empty string is supplied for the argument aBuffer, it indicates that there is be no more data 
       
   299 to feed through this function.  Such a function call must be done to indicate that all 3GP/MP4/3G2 
       
   300 data has been written to the library's internal memory.
       
   301 
       
   302 @param	aBuffer	The descriptor containing the data to be inserted.
       
   303 
       
   304 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   305 		KErrGeneral		if an error has no specific categorisation;
       
   306 		KErrNoMemory	if parser cannot allocate enough memory for the data;
       
   307 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
   308 */
       
   309 EXPORT_C TInt C3GPParse::InsertData(const TDesC8& aBuffer)
       
   310 	{
       
   311 	if (!iHandler)
       
   312 		{
       
   313 		return KErrNotReady;
       
   314 		}
       
   315 
       
   316 	return SymbianOSError(MP4ParseWriteData(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), aBuffer.Length()));
       
   317 	}
       
   318 
       
   319 /**
       
   320 This function returns the parameters describing the video stream. 
       
   321 
       
   322 If no file or CAF object is supplied during parser initialisation, this should be called after 
       
   323 enough data has been inserted into the library buffers so that the 3GP headers containing the 
       
   324 information can be read.
       
   325 
       
   326 The aFrameRate parameter refers to the frame rate of the original video material.
       
   327 
       
   328 @param	aType			The type of video stream.  Refer to T3GPVideoType for supported video type.
       
   329 @param	aLength			Duration of video in milliseconds.
       
   330 @param	aFrameRate		Average frame rate of video (in Hz).
       
   331 @param	aAvgBitRate		Average bit rate of video.
       
   332 @param	aSize			Width and height of video image measured in pixels.
       
   333 @param	aTimeScale		Timescale of video track.  
       
   334 
       
   335 @return	KErrNone 			if successful.  Otherwise, returns one of the system wide error codes.
       
   336 		KErrGeneral			if an error has no specific categorisation;
       
   337 		KErrNotSupported	if the input does not contain video;
       
   338 		KErrCorrupt			if 3GP stream is invalid;
       
   339 		KErrNotReady		if the parser has not yet been initialised; See C3GPParse::Open;
       
   340 		KErr3gpLibMoreDataRequired	if more data is required before the requested information can be 
       
   341 							retrieved;  See C3GPParse::InsertData.
       
   342 */
       
   343 EXPORT_C TInt C3GPParse::GetVideoProperties(T3GPVideoType& aType, TUint& aLength, TReal& aFrameRate, 
       
   344 		TUint& aAvgBitRate, TSize& aSize, TUint& aTimeScale) const
       
   345 	{
       
   346 	if (!iHandler)
       
   347 		{
       
   348 		return KErrNotReady;
       
   349 		}
       
   350 	
       
   351 	TInt err = DoGetVideoProperties();
       
   352 	
       
   353 	if (err == KErrNone)
       
   354 		{
       
   355 		aLength = iVideoLength;
       
   356 		aType = iVideoType;
       
   357 		aFrameRate = iVideoFrameRate;
       
   358 		aSize.iWidth = iVideoSize.iWidth;
       
   359 		aSize.iHeight = iVideoSize.iHeight;
       
   360 		aTimeScale = iVideoTimeScale;
       
   361 		}
       
   362 	else 
       
   363 		{
       
   364 		return err;
       
   365 		}
       
   366 
       
   367 	// Get average bit rate of the stream in bps
       
   368 	err = DoGetStreamProperties();
       
   369 	if (err != KErrNone)
       
   370 		{
       
   371 		return err;
       
   372 		}
       
   373 	
       
   374 	// Video average bit rate is calculated from GetStreamDescription’s aAvgBitRate substructs Audio’s aAvgBitRate
       
   375 	// GetAudioProperties has not been called
       
   376 	err = DoGetAudioProperties();
       
   377 	if (err == KErrNone)
       
   378 		{
       
   379 		aAvgBitRate = iStreamAvgBitRate - iAudioAvgBitRate;
       
   380 		}
       
   381 	else
       
   382 		{
       
   383 		// if the audio stream is not usable, ignore the error since the stream
       
   384 		// in concern is video stream.  The audio stream error can be dealt with by
       
   385 		// users when it asks for audio properties. 
       
   386 		aAvgBitRate = iStreamAvgBitRate;
       
   387 		}
       
   388 	
       
   389 	return KErrNone;
       
   390 	}
       
   391 
       
   392 /**
       
   393 This function returns the parameters describing the audio stream. 
       
   394  
       
   395 If no file or CAF object is supplied during parser initialisation, this should be called after 
       
   396 enough data has been inserted into the library so that the 3GP headers containing the information 
       
   397 can be read.
       
   398 
       
   399 @param	aType		The type of audio stream.  Refer to T3GPFrameType for supported audio type values.
       
   400 @param	aLength		Duration of audio in milliseconds.
       
   401 @param	aFramesPerSample	Number of audio frames in each sample.
       
   402 @param	aAvgBitRate	Average bit rate of audio.
       
   403 @param	aTimeScale	Timescale of audio track. 
       
   404 
       
   405 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   406 		KErrGeneral		if an error has no specific categorisation;
       
   407 		KErrNotSupported	if input does not contain audio;
       
   408 		KErrCorrupt		if 3GP stream is invalid;
       
   409 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   410 		KErr3gpLibMoreDataRequired	if more data is required before the requested information can be 
       
   411 						retrieved.  See C3GPParse::InsertData.
       
   412 */
       
   413 EXPORT_C TInt C3GPParse::GetAudioProperties(T3GPAudioType& aType, TUint& aLength, TInt& aFramesPerSample, 
       
   414 		TUint& aAvgBitRate, TUint& aTimeScale) const
       
   415 	{
       
   416 	if (!iHandler)
       
   417 		{
       
   418 		return KErrNotReady;
       
   419 		}
       
   420 	
       
   421 	TInt err = DoGetAudioProperties();
       
   422 	
       
   423 	if (err == KErrNone)
       
   424 		{
       
   425 		aLength = iAudioLength;
       
   426 		aType = iAudioType;
       
   427 		aFramesPerSample = iAudioFramesPerSample;
       
   428 		aAvgBitRate = iAudioAvgBitRate;
       
   429 		aTimeScale = iAudioTimeScale;
       
   430 		iAudioPropertiesSaved = ETrue;
       
   431 		}
       
   432 
       
   433 	return err;
       
   434 	}
       
   435 
       
   436 /**
       
   437 This function returns the parameters that describe the contents of the input file or buffer. 
       
   438 
       
   439 If no file or CAF object is supplied during parser initialisation, this should be called after 
       
   440 enough data has been inserted into the library so that the headers containing the information can 
       
   441 be read.
       
   442 
       
   443 @param	aSize		Length of the stream in bytes.
       
   444 @param	aAvgBitRate	Average bit rate of the stream in bps.
       
   445 
       
   446 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   447 		KErrGeneral		if an error has no specific categorisation;
       
   448 		KErrCorrupt		if 3GP stream is invalid;
       
   449 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   450 		KErr3gpLibMoreDataRequired	if more data is required before the requested information can be 
       
   451 						retrieved.  See C3GPParse::InsertData.
       
   452  */
       
   453 EXPORT_C TInt C3GPParse::GetContainerProperties(TUint& aSize, TUint& aAvgBitRate) const
       
   454 	{
       
   455 	if (!iHandler)
       
   456 		{
       
   457 		return KErrNotReady;
       
   458 		}
       
   459 	
       
   460 	TInt err = DoGetStreamProperties();
       
   461 	if (err == KErrNone)
       
   462 		{
       
   463 		aSize = iStreamSize;
       
   464 		aAvgBitRate = iStreamAvgBitRate;
       
   465 		}
       
   466 
       
   467 	return err;
       
   468 	}
       
   469 
       
   470 /**
       
   471 This function returns the number of bytes that the library instance has in its allocated buffers.
       
   472 
       
   473 The function is only valid when the parser is initialized without any parameters. Zero is 
       
   474 returned when in file mode, that is, the parser has been initialized with a valid filename, file handle 
       
   475 or a CAF object.
       
   476 
       
   477 @see C3GPParse::InsertData.
       
   478 
       
   479 @param	aNum	Number of allocated bytes in the library.
       
   480 
       
   481 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   482 		KErrGeneral		if an error has no specific categorisation;
       
   483 		KErrNotSupported	if the parser has been initialised with a file name or file handle;
       
   484 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
   485 */
       
   486 EXPORT_C TInt C3GPParse::GetNumBufferedBytes(TInt& aNum) const
       
   487 	{
       
   488 	if (!iHandler)
       
   489 		{
       
   490 		return KErrNotReady;
       
   491 		}
       
   492 		
       
   493 	mp4_u32 numBytes = 0;
       
   494 	MP4Err mp4Err = MP4ParseGetBufferedBytes(iHandler, &numBytes);
       
   495 	aNum = numBytes;
       
   496 	
       
   497 	return SymbianOSError(mp4Err);
       
   498 	}
       
   499 
       
   500 /**
       
   501 This function returns the type of the next audio/video frame in the stream.
       
   502 
       
   503 This function has no effect on the parser’s current position.
       
   504 
       
   505 @param	aType	Type of the next frame.  Refer to the definition of T3GPFrameType for all possible values.
       
   506 
       
   507 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   508 		KErrGeneral		if an error has no specific categorisation;
       
   509 		KErrNotFound	if frame does not exist (the previous frame was the last one);
       
   510 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   511 		KErrCorrupt		if 3GP stream is invalid;
       
   512 		KErr3gpLibMoreDataRequired		if 3GP library needs more data before the requested 
       
   513 						information can be returned.
       
   514 */
       
   515 EXPORT_C TInt C3GPParse::GetFrameType(T3GPFrameType& aType) const
       
   516 	{
       
   517 	if (!iHandler)
       
   518 		{
       
   519 		return KErrNotReady;
       
   520 		}
       
   521 	mp4_u32 frameType = 0;
       
   522 	MP4Err mp4Err = MP4ParseNextFrameType(iHandler, &frameType);
       
   523 	if (mp4Err == MP4_OK)
       
   524 		{
       
   525 		if (
       
   526 		        frameType == MP4_TYPE_MPEG4_VIDEO ||
       
   527 		        frameType == MP4_TYPE_H263_PROFILE_0 || 
       
   528 		        frameType == MP4_TYPE_H263_PROFILE_3 ||
       
   529 		        frameType == MP4_TYPE_AVC_PROFILE_BASELINE ||
       
   530                 frameType == MP4_TYPE_AVC_PROFILE_MAIN ||
       
   531                 frameType == MP4_TYPE_AVC_PROFILE_EXTENDED ||
       
   532                 frameType == MP4_TYPE_AVC_PROFILE_HIGH
       
   533 		   )
       
   534 			{
       
   535 			aType = E3GPVideo;
       
   536 			}
       
   537 		else if (frameType == MP4_TYPE_MPEG4_AUDIO || frameType == MP4_TYPE_AMR_NB || 
       
   538 			frameType == MP4_TYPE_AMR_WB || frameType == MP4_TYPE_QCELP_13K)
       
   539 			{
       
   540 			aType = E3GPAudio;
       
   541 			}
       
   542 		else
       
   543 			{
       
   544 			// This should not happen
       
   545 			Panic(KErrCorrupt);
       
   546 			}
       
   547 		}
       
   548 	return SymbianOSError(mp4Err);
       
   549 	}
       
   550 
       
   551 /**
       
   552 This function returns the size of the immediate next video frame based on the current 
       
   553 position of the parser.
       
   554 
       
   555 Calling this function does not change the current position of the parser.
       
   556 
       
   557 @param	aSize	Size of the next video frame in bytes.
       
   558 
       
   559 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   560 		KErrGeneral		if an error has no specific categorisation;
       
   561 		KErrNotSupported	if the input does not contain video;		
       
   562 		KErrCorrupt		if 3GP stream is invalid;
       
   563 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   564 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   565 						information can be returned.
       
   566 */
       
   567 EXPORT_C TInt C3GPParse::GetVideoFrameSize(TUint& aSize) const
       
   568 	{
       
   569 	if (!iHandler)
       
   570 		{
       
   571 		return KErrNotReady;
       
   572 		}
       
   573 	
       
   574 	// Check if 3GP input data contains video stream
       
   575 	TInt err = DoGetVideoProperties(); 
       
   576 	if (err != KErrNone)
       
   577 		{
       
   578 		return err;
       
   579 		}
       
   580 	
       
   581 	// video type from 3GP file header has been saved
       
   582 	mp4_u32 frameSize = 0;	
       
   583 	MP4Err mp4Err = MP4ParseNextFrameSize(iHandler, iVideoMp4Type, &frameSize);
       
   584 	if (mp4Err == MP4_OK)
       
   585 		{		
       
   586 		aSize = frameSize;
       
   587 		}
       
   588 	
       
   589 	return SymbianOSError(mp4Err);	
       
   590 	}
       
   591 
       
   592 /**
       
   593 This function returns the total size of the audio frames in the immediate audio sample based on the 
       
   594 current position of the parser.
       
   595 
       
   596 This function has no effect on the parser’s current position.
       
   597 
       
   598 @param	aSize	Size of the next audio sample in bytes.
       
   599 
       
   600 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   601 		KErrGeneral		if an error has no specific categorisation;
       
   602 		KErrNotSupported	if the input does not contain audio;
       
   603 		KErrCorrupt		if 3GP stream is invalid;
       
   604 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   605 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   606 						information can be returned.
       
   607 */
       
   608 EXPORT_C TInt C3GPParse::GetAudioFramesSize(TUint& aSize) const
       
   609 	{
       
   610 	if (!iHandler)
       
   611 		{
       
   612 		return KErrNotReady;
       
   613 		}
       
   614 	
       
   615 	// Check if 3GP input data contains audio stream
       
   616 	TInt err = DoGetAudioProperties(); 
       
   617 	if (err != KErrNone)
       
   618 		{
       
   619 		return err;
       
   620 		}
       
   621 	
       
   622 	// audio type from 3GP file header has been saved. Directely use iAudioMp4Type as input
       
   623 	mp4_u32 frameSize = 0;
       
   624 	
       
   625 	MP4Err mp4Err = MP4ParseNextFrameSize(iHandler, iAudioMp4Type, &frameSize);
       
   626 	if (mp4Err == MP4_OK)
       
   627 		{
       
   628 		aSize = frameSize;
       
   629 		}
       
   630 	
       
   631 	return SymbianOSError(mp4Err);	
       
   632 	}
       
   633 
       
   634 /**
       
   635 This function reads the next video frame from the 3GP file/stream and returns it to the caller.  
       
   636 The current position of video stream will be moved forward.
       
   637 
       
   638 The next frame depends on the position in the input 3GP file.  C3GPParse::Seek can be used to change 
       
   639 the current position in the 3GP file.
       
   640 
       
   641 If the function returns KErr3gpLibMoreDataRequired, the caller needs to call C3GPParse::InsertData 
       
   642 to insert more data before calling the function again.
       
   643 
       
   644 Since there are separate cursors for storing current positions of video and audio streams, calling this 
       
   645 function does not affect the position of the next audio stream.
       
   646 
       
   647 @param	aBuffer		Video frame is returned here.
       
   648 @param	aKeyFrame	Returns ETrue if the current frame is a key frame (intra), otherwise the value is EFalse.
       
   649 @param	aTimeStampInMs	Video frame presentation time in milliseconds from the beginning of the video sequence.
       
   650 @param	aTimeStampInTimescale	Video frame presentation time in timescale from the beginning of the video sequence.  
       
   651 
       
   652 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
   653 		KErrGeneral		if an error has no specific categorisation;
       
   654 		KErrNotSupported	if the 3GP input data contains no video stream;
       
   655 		KErrNotFound	if frame does not exist (the previous frame was the last one);
       
   656 		KErrOverflow	if requested frame does not fit into the given buffer; Caller can use 
       
   657 						C3GPParse::GetVideoFrameSize to retrieve the minimum buffer size needed 
       
   658 						to fit this video frame;
       
   659 		KErrCorrupt		if 3GP stream is invalid;
       
   660 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   661 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   662 						information can be returned.
       
   663 */
       
   664 EXPORT_C TInt C3GPParse::ReadVideoFrame(TDes8& aBuffer, TBool& aKeyFrame, TUint& aTimeStampInMs, 
       
   665 										TUint& aTimeStampInTimescale) const
       
   666 	{
       
   667 	if (!iHandler)
       
   668 		{
       
   669 		return KErrNotReady;
       
   670 		}
       
   671 	if (aBuffer.MaxLength() <= 0)
       
   672 		{
       
   673 		return KErrOverflow;
       
   674 		}
       
   675 	
       
   676 	// Check if 3GP input data contains video stream
       
   677 	TInt err = DoGetVideoProperties();	
       
   678 	if (err != KErrNone)
       
   679 		{
       
   680 		return err;
       
   681 		}
       
   682 	
       
   683 	mp4_u32 frameSize = 0;
       
   684 	mp4_u32 timeStamp = 0;
       
   685 	mp4_bool keyFrame = EFalse; 
       
   686 	mp4_u32 timestamp2 = 0;
       
   687 	
       
   688 	MP4Err mp4Err = MP4ParseReadVideoFrame(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), aBuffer.MaxLength(), 
       
   689 			&frameSize, &timeStamp, &keyFrame, &timestamp2);
       
   690 	
       
   691 	if (mp4Err == MP4_OK)
       
   692 		{
       
   693 		aBuffer.SetLength(frameSize);
       
   694 		aKeyFrame = keyFrame;
       
   695 		aTimeStampInMs = timeStamp;
       
   696 		aTimeStampInTimescale = timestamp2;
       
   697 		}
       
   698 	return SymbianOSError(mp4Err);
       
   699 	}
       
   700 
       
   701 /**
       
   702 Return size of video DecoderSpecificInfo.
       
   703 For files with MPEG-4 video this data is read from the esds atom. For files with AVC video
       
   704 this data is read from the avcC atom.
       
   705 
       
   706 Note: Only MPEG-4 video and H.264/AVC video streams contain DecoderSpecificInfo.
       
   707 
       
   708 @param	aSize	Size of video DecoderSpecificInfo.
       
   709 
       
   710 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
   711 		KErrGeneral		if an error has no specific categorisation;
       
   712 		KErrNotSupported	if the 3GP input data contains no MPEG-4 / AVC video stream;
       
   713 		KErrCorrupt		if 3GP stream is invalid;
       
   714 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   715 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   716 						information can be returned.
       
   717 */
       
   718 EXPORT_C TInt C3GPParse::GetVideoDecoderSpecificInfoSize(TInt& aSize) const
       
   719 	{
       
   720 	if (!iHandler)
       
   721 		{
       
   722 		return KErrNotReady;
       
   723 		}
       
   724 
       
   725 	// Check if 3GP input data contains video stream and the video type is either
       
   726 	// MPEG-4 or H.264/AVC
       
   727 	TInt err = DoGetVideoProperties();	
       
   728 	if (err == KErrNone)
       
   729 		{
       
   730 		if (!(
       
   731 		        iVideoType == E3GPMpeg4Video ||
       
   732 		        iVideoType == E3GPAvcProfileBaseline ||
       
   733 				iVideoType == E3GPAvcProfileMain ||
       
   734 				iVideoType == E3GPAvcProfileExtended ||
       
   735                 iVideoType == E3GPAvcProfileHigh
       
   736         ))
       
   737 			{
       
   738 			return KErrNotSupported;
       
   739 			}
       
   740 		}
       
   741 	else
       
   742 		{
       
   743 		return err;
       
   744 		}
       
   745 	
       
   746 	mp4_u32 decspecinfosize = 0;
       
   747 	MP4Err mp4Err = MP4ParseReadVideoDecoderSpecificInfo(iHandler, NULL, 0, &decspecinfosize);
       
   748 	
       
   749 	if ( mp4Err == MP4_OK || mp4Err == MP4_BUFFER_TOO_SMALL)
       
   750 		{
       
   751 		aSize = decspecinfosize;
       
   752 		mp4Err = MP4_OK;
       
   753 		}
       
   754 
       
   755 	return SymbianOSError(mp4Err);
       
   756 	}
       
   757 
       
   758 /**
       
   759 This function reads DecoderSpecificInfo data from 3GP metadata and returns it to the caller.
       
   760 For files with MPEG-4 video this data is read from the esds atom. For files with AVC video
       
   761 this data is read from the avcC atom.
       
   762 
       
   763 Note: Only MPEG-4 video and H.264/AVC video streams contain DecoderSpecificInfo.
       
   764 
       
   765 @see C3GPParse::GetVideoDecoderSpecificInfoSize
       
   766 
       
   767 @param	aInfo			The descriptor to store the video decoder information.
       
   768 
       
   769 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
   770 		KErrGeneral		if an error has no specific categorisation;
       
   771 		KErrNotSupported	if the 3GP input data contains no MPEG-4 / AVC video stream;
       
   772 		KErrOverflow	if requested frame does not fit into the given buffer;
       
   773 		KErrCorrupt		if 3GP stream is invalid;
       
   774 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   775 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   776 						information can be returned.
       
   777 */
       
   778 EXPORT_C TInt C3GPParse::GetVideoDecoderSpecificInfo(TDes8& aInfo) const
       
   779 	{
       
   780 	if (!iHandler)
       
   781 		{
       
   782 		return KErrNotReady;
       
   783 		}
       
   784 	if (aInfo.MaxLength() <= 0)
       
   785 		{
       
   786 		return KErrOverflow;
       
   787 		}
       
   788 	
       
   789 	// Check if 3GP input data contains video stream and the video type is either
       
   790 	// MPEG-4 or H.264/AVC
       
   791 	TInt err = DoGetVideoProperties();	
       
   792 	if (err == KErrNone)
       
   793 		{
       
   794 		if (!(
       
   795 		        iVideoType == E3GPMpeg4Video ||
       
   796 		        iVideoType == E3GPAvcProfileBaseline ||
       
   797 		        iVideoType == E3GPAvcProfileMain ||
       
   798 		        iVideoType == E3GPAvcProfileExtended ||
       
   799                 iVideoType == E3GPAvcProfileHigh
       
   800 		))
       
   801 			{
       
   802 			return KErrNotSupported;
       
   803 			}
       
   804 		}
       
   805 	else
       
   806 		{
       
   807 		return err;
       
   808 		}
       
   809 	
       
   810 	mp4_u32 decspecinfosize = 0;
       
   811 	MP4Err mp4Err = MP4ParseReadVideoDecoderSpecificInfo(iHandler, const_cast<mp4_u8*>(aInfo.Ptr()), 
       
   812 			aInfo.MaxLength(),&decspecinfosize);
       
   813 	if (mp4Err == MP4_OK)
       
   814 		{
       
   815 		aInfo.SetLength(decspecinfosize);
       
   816 		}	
       
   817 	return SymbianOSError(mp4Err);
       
   818 	}
       
   819 
       
   820 /**
       
   821 This function reads the audio frames that are stored in the current audio sample from the 
       
   822 3GP file/stream and returns them to the caller.  The current position of audio stream will be moved forward. 
       
   823 
       
   824 Note: The next frame depends on the position in the input 3GP file.  C3GPParse::Seek can 
       
   825 be used to change the current position in the 3GP file.
       
   826 
       
   827 If the function returns KErr3gpLibMoreDataRequired, the caller needs to call C3GPParse::InsertData 
       
   828 to insert more data before calling the function again.
       
   829 
       
   830 Note: aReturnedFrames may differ from the correct value when accessing the last audio sample.
       
   831 
       
   832 Note: Since there are separate cursors for storing current positions for video and audio streams, calling 
       
   833 this function does not change current position of the parser for video stream.
       
   834 
       
   835 @param	aBuffer			Audio frames are returned here.
       
   836 @param	aReturnedFrames	Number of the returned frames or 0 if not known.
       
   837 @param	aTimeStampInMs	Audio frame presentation time in milliseconds from the beginning of the 
       
   838 						audio sequence.
       
   839 @param	aTimeStampInTimescale	Audio frame presentation time in timescale from the beginning 
       
   840 						of the audio sequence.  
       
   841 					
       
   842 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
   843 		KErrGeneral		if an error has no specific categorisation;
       
   844 		KErrNotSupported	if the 3GP input data contains no audio stream; 
       
   845 		KErrOverflow	if requested frame does not fit into the given buffer; Caller can use 
       
   846 						C3GPParse::GetAudioFrameSize to retrieve the minimum size needed to 
       
   847 						fit this audio frame;
       
   848 		KErrCorrupt		if 3GP stream is invalid;
       
   849 		KErrNotFound	if no more frames available;
       
   850 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   851 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   852 						information can be returned.
       
   853 */
       
   854 EXPORT_C TInt C3GPParse::ReadAudioFrames(TDes8& aBuffer, TInt& aReturnedFrames, TUint& aTimeStampInMs, 
       
   855 		TUint& aTimeStampInTimescale) const
       
   856 	{
       
   857 	if (!iHandler)
       
   858 		{
       
   859 		return KErrNotReady;
       
   860 		}
       
   861 	if (aBuffer.MaxLength() <= 0)
       
   862 		{
       
   863 		return KErrOverflow;
       
   864 		}
       
   865 	
       
   866 	// Check if 3GP input data contains audio stream
       
   867 	TInt err = DoGetAudioProperties();	
       
   868 	if (err != KErrNone)
       
   869 		{
       
   870 		return err;
       
   871 		}
       
   872 	
       
   873 	mp4_u32 numOfFrames = 0;
       
   874 	mp4_u32 timeStampInMs = 0;
       
   875 	mp4_u32 timeStampInTimescale = 0;
       
   876 	mp4_u32 audioSize = 0;
       
   877 	MP4Err mp4Err = MP4ParseReadAudioFrames(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), aBuffer.MaxLength(), 
       
   878 			&audioSize, &timeStampInMs, &numOfFrames, &timeStampInTimescale);
       
   879 	if (mp4Err == MP4_OK)
       
   880 		{
       
   881 		aBuffer.SetLength(audioSize);
       
   882 		aReturnedFrames = numOfFrames;
       
   883 		aTimeStampInMs = timeStampInMs;
       
   884 		aTimeStampInTimescale = timeStampInTimescale;	
       
   885 		}
       
   886 	return SymbianOSError(mp4Err);
       
   887 	}
       
   888 
       
   889 /**
       
   890 Returns size of audio DecoderSpecificInfo data from 3GP metadata.
       
   891 
       
   892 @param	aSize	Size of DecoderSpecificInfo to be returned (in bytes).
       
   893 
       
   894 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
   895 		KErrGeneral		if an error has no specific categorisation;
       
   896 		KErrNotSupported	if the stream does not contain audio stream stored in MPEG-4 audio sample boxes.
       
   897 		KErrCorrupt		if 3GP stream is invalid;
       
   898 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   899 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   900 						information can be returned.
       
   901 */
       
   902 EXPORT_C TInt C3GPParse::GetAudioDecoderSpecificInfoSize(TInt& aSize) const
       
   903 	{
       
   904 	if (!iHandler)
       
   905 		{
       
   906 		return KErrNotReady;
       
   907 		}
       
   908 
       
   909 	// Check if 3GP input data contains audio stream
       
   910 	TInt err = DoGetAudioProperties();	
       
   911 	if (err != KErrNone)
       
   912 		{
       
   913 		return err;
       
   914 		}
       
   915 	
       
   916 	mp4_u32 decspecinfosize = 0;
       
   917 	MP4Err mp4Err = MP4ParseReadAudioDecoderSpecificInfo(iHandler, NULL, 0, &decspecinfosize);	
       
   918 	if ( mp4Err == MP4_OK  || mp4Err == MP4_BUFFER_TOO_SMALL)
       
   919 		{
       
   920 		aSize = decspecinfosize;
       
   921 		mp4Err = MP4_OK;
       
   922 		}	
       
   923 	return SymbianOSError(mp4Err);
       
   924 	}
       
   925 
       
   926 /**
       
   927 This function reads DecoderSpecificInfo data from 3GP metadata and returns it to the caller.
       
   928 
       
   929 Note: AMR DecoderSpecificInfo data structure is returned in runtime in an architecture-specific 
       
   930 Endian format, that is, no Endian conversion is necessary for the data.
       
   931 
       
   932 @see C3GPParse::GetAudioDecoderSpecificInfoSize
       
   933 
       
   934 @param	aBuffer				DecoderSpecificInfo is returned here.
       
   935 
       
   936 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
   937 		KErrGeneral		if an error has no specific categorisation;
       
   938 		KErrNotSupported	if the stream does not contain audio stream stored in MPEG-4 audio sample boxes.		
       
   939 		KErrOverflow	if requested frame does not fit into the given buffer;
       
   940 		KErrCorrupt		if 3GP stream is invalid;
       
   941 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   942 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   943 						information can be returned.
       
   944 */
       
   945 EXPORT_C TInt C3GPParse::GetAudioDecoderSpecificInfo(TDes8& aBuffer) const
       
   946 	{
       
   947 	if (!iHandler)
       
   948 		{
       
   949 		return KErrNotReady;
       
   950 		}
       
   951 	if (aBuffer.MaxLength() <= 0)
       
   952 		{
       
   953 		return KErrOverflow;
       
   954 		}
       
   955 	
       
   956 	// Check if 3GP input data contains audio stream
       
   957 	TInt err = DoGetAudioProperties();	
       
   958 	if (err != KErrNone)
       
   959 		{
       
   960 		return err;
       
   961 		}
       
   962 	
       
   963 	mp4_u32 decspecinfosize = 0;
       
   964 	MP4Err mp4Err = MP4ParseReadAudioDecoderSpecificInfo(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), 
       
   965 			aBuffer.MaxLength(),&decspecinfosize);
       
   966 	if (mp4Err == MP4_OK)
       
   967 		{
       
   968 		aBuffer.SetLength(decspecinfosize);
       
   969 		}
       
   970 	return SymbianOSError(mp4Err);
       
   971 	}
       
   972 
       
   973 /**
       
   974 Returns the timestamp of the next video frame.  The current position of the video stream will be moved forward.
       
   975 
       
   976 The function can be used to find out which frames have been coded to optimize the input frame selection 
       
   977 if video frame rate needs to be modified.
       
   978 
       
   979 When this function call returns KErrEof, there are no more video frames left in the 3GP file and 
       
   980 the timestamp returned with the previous call was the timestamp of the last video frame.
       
   981 
       
   982 Note:  C3GPParse::Seek can be used to change the current position in the 3GP file. 
       
   983 
       
   984 @param	aTimeStampInMs			Timestamp in milliseconds is returned here.
       
   985 @param	aTimeStampInTimescale	Timestamp in timescale is returned here.  
       
   986 
       
   987 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
   988 		KErrGeneral		if an error has no specific categorisation;
       
   989 		KErrNotSupported	if the input does not contain video;		
       
   990 		KErrEof			if no more video frames left;
       
   991 		KErrCorrupt		if 3GP stream is invalid;
       
   992 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
   993 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
   994 						information can be returned.
       
   995 */
       
   996 EXPORT_C TInt C3GPParse::GetVideoTimestamp(TUint& aTimeStampInMs, TUint& aTimeStampInTimescale) const
       
   997 	{
       
   998 	if (!iHandler)
       
   999 		{
       
  1000 		return KErrNotReady;
       
  1001 		}
       
  1002 	
       
  1003 	// Check if 3GP input data contains video stream
       
  1004 	TInt err = DoGetVideoProperties();	
       
  1005 	if (err != KErrNone)
       
  1006 		{
       
  1007 		return err;
       
  1008 		}
       
  1009 	
       
  1010 	mp4_u32 timeStampInMs = 0;
       
  1011 	mp4_u32 timeStampInTimescale = 0;
       
  1012 	MP4Err mp4Err = MP4ParseGetNextVideoTimestamp(iHandler, &timeStampInMs, &timeStampInTimescale);
       
  1013 	if (mp4Err == MP4_OK)
       
  1014 		{
       
  1015 		aTimeStampInMs = timeStampInMs;
       
  1016 		aTimeStampInTimescale = timeStampInTimescale;
       
  1017 		}
       
  1018 	return SymbianOSError(mp4Err);
       
  1019 	}
       
  1020 
       
  1021 /**
       
  1022 This function determines whether the input 3GP stream is streamable, that is, whether the media data is arranged 
       
  1023 in such a manner that playback can be started without downloading the entire stream.
       
  1024 
       
  1025 @param	aStreamable	Returns ETrue if the file is streamable.  Otherwise, returns EFalse.
       
  1026 
       
  1027 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1028 		KErrGeneral		if an error has no specific categorisation;
       
  1029 		KErrCorrupt		if 3GP stream is invalid;
       
  1030 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
  1031 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
  1032 						information can be returned.
       
  1033 */
       
  1034 EXPORT_C TInt C3GPParse::GetStreamable(TBool& aStreamable) const
       
  1035 	{
       
  1036 	if (!iHandler)
       
  1037 		{
       
  1038 		return KErrNotReady;
       
  1039 		}
       
  1040 	
       
  1041 	MP4Err mp4Err = MP4ParseIsStreamable(iHandler);
       
  1042 	if (mp4Err == MP4_OK)
       
  1043 		{
       
  1044 		aStreamable = ETrue;
       
  1045 		}
       
  1046 	else
       
  1047 		{
       
  1048 		aStreamable = EFalse;
       
  1049 		}
       
  1050 	return SymbianOSError(mp4Err);
       
  1051 	}
       
  1052 
       
  1053 /**
       
  1054 This function seeks the position specified by the aPosition parameter in the input 3GP file/stream. 
       
  1055 
       
  1056 The position is considered to start from the beginning of the presentation time line in the 3GP file. 
       
  1057 Thus audio and video positions cannot be given separately.
       
  1058 
       
  1059 The function will set the current audio and video positions in the following manner:
       
  1060 
       
  1061 	If there is only audio data in the file, the current position is set to the audio frame at or just 
       
  1062 	before the given position.
       
  1063 
       
  1064 	If there is only video in the file and the key frame is EFalse, the current position is set to the 
       
  1065 	video frame at or just before the given position. If the key frame is set to ETrue, the current 
       
  1066 	position is set to the first key frame at or before the current position.
       
  1067 
       
  1068 	If there are both audio and video in the file, video is first positioned as explained above and then 
       
  1069 	audio is sought to the closest position in relation to video.	
       
  1070 	
       
  1071 If the position to seek is greater than the duration of video or audio, the video or audio position is 
       
  1072 set to the position of the last video or audio frame as explained above.
       
  1073 
       
  1074 If the function returns KErr3gpLibMoreDataRequired, the caller needs to call C3GPParse::InsertData 
       
  1075 to insert more data before calling the function again.
       
  1076 
       
  1077 @param	aPosition		Position to seek in milliseconds in the 3GP presentation time line.
       
  1078 @param	aKeyFrame		If set to ETrue, the first video key frame before a given point is sought.  If 
       
  1079 						set to EFalse, the first video frame before a given point is sought.
       
  1080 @param	aAudioPosition	Position of audio after seeking (in milliseconds).
       
  1081 @param	aVideoPosition	Position of video after seeking (in milliseconds).
       
  1082 
       
  1083 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1084 		KErrGeneral		if an error has no specific categorisation;
       
  1085 		KErrNotFound	if cannot seek the requested position;
       
  1086 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
  1087 						information can be returned.
       
  1088 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
  1089 */
       
  1090 EXPORT_C TInt C3GPParse::Seek(TUint aPosition, TBool aKeyFrame, TUint& aAudioPosition, TUint& aVideoPosition) const
       
  1091 	{
       
  1092 	if (!iHandler)
       
  1093 		{
       
  1094 		return KErrNotReady;
       
  1095 		}
       
  1096 	
       
  1097 	mp4_u32 audioPosition = 0;
       
  1098 	mp4_u32 videoPosition = 0;
       
  1099 	mp4_bool keyFrame = aKeyFrame;
       
  1100 	MP4Err mp4Err = MP4ParseSeek(iHandler, aPosition, &audioPosition, &videoPosition, keyFrame);
       
  1101 	if (mp4Err == MP4_OK)
       
  1102 		{
       
  1103 		aAudioPosition = audioPosition;
       
  1104 		aVideoPosition = videoPosition;
       
  1105 		}
       
  1106 	return SymbianOSError(mp4Err);
       
  1107 	}
       
  1108 
       
  1109 /**
       
  1110 This function determines whether the next frame of the type aType is available.
       
  1111 
       
  1112 This function has no effect on the parser’s current position.
       
  1113 
       
  1114 @param	aType		The type of frame to check for.  Refer to T3GPFrameType for supported types.
       
  1115 @param	aAvailable	Return ETrue if the type of frame specified by aType is available.
       
  1116 
       
  1117 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1118 		KErrGeneral		if an error has no specific categorisation;
       
  1119 		KErrNotFound	if frame of the requested type is not available;
       
  1120 		KErrCorrupt		if 3GP stream is invalid;
       
  1121 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
  1122 		KErr3gpLibMoreDataRequired	if 3GP library needs more data before the requested 
       
  1123 						information can be returned.
       
  1124 */
       
  1125 EXPORT_C TInt C3GPParse::GetFrameAvailability(T3GPFrameType aType, TBool& aAvailable) const
       
  1126 	{
       
  1127 	if (!iHandler)
       
  1128 		{
       
  1129 		return KErrNotReady;
       
  1130 		}
       
  1131 	
       
  1132 	aAvailable = EFalse;
       
  1133 	TInt err = KErrNone;
       
  1134 	MP4Err mp4Err = MP4_OK;
       
  1135 	if (aType == E3GPAudio)
       
  1136 		{
       
  1137 		// Check if 3GP input data contains audio stream
       
  1138 		err = DoGetAudioProperties();	
       
  1139 		if (err == KErrNotSupported)
       
  1140 			{
       
  1141 			// If there is no requested type, err will be KErrNotSupported. But in here, KErrNotFound is 
       
  1142 			// more proper.
       
  1143 			err = KErrNotFound;
       
  1144 			}
       
  1145 		else if (err == KErrNone)
       
  1146 			{
       
  1147 			mp4Err = MP4ParseIsFrameAvailable(iHandler, iAudioMp4Type);
       
  1148 			err = SymbianOSError(mp4Err);
       
  1149 			}
       
  1150 		}
       
  1151 	else if (aType == E3GPVideo) 
       
  1152 		{
       
  1153 		// Check if 3GP input data contains video stream
       
  1154 		err = DoGetVideoProperties();	
       
  1155 		if (err == KErrNotSupported)
       
  1156 			{
       
  1157 			// If there is no requested type, err will be KErrNotSupported. But in here, KErrNotFound is 
       
  1158 			// more proper.
       
  1159 			err = KErrNotFound;
       
  1160 			}
       
  1161 		else if (err == KErrNone)
       
  1162 			{
       
  1163 			mp4Err = MP4ParseIsFrameAvailable(iHandler, iVideoMp4Type);
       
  1164 			err = SymbianOSError(mp4Err);
       
  1165 			}
       
  1166 		}
       
  1167 	else
       
  1168 		{
       
  1169 		Panic(KErrArgument); // This should not happen.
       
  1170 		}
       
  1171 	
       
  1172 	if (err == KErrNone)
       
  1173 		{
       
  1174 		aAvailable = ETrue;
       
  1175 		}
       
  1176 	return err;
       
  1177 	}
       
  1178 
       
  1179 /**
       
  1180 Returns the number of video frames.
       
  1181 
       
  1182 @param	aNum	Number of video frames.
       
  1183 
       
  1184 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1185 		KErrGeneral		if an error has no specific categorisation;
       
  1186 		KErrNotSupported	if the input does not contain video;		
       
  1187 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1188 */
       
  1189 EXPORT_C TInt C3GPParse::GetNumberOfVideoFrames(TUint& aNum) const
       
  1190 	{
       
  1191 	if (!iHandler)
       
  1192 		{
       
  1193 		return KErrNotReady;
       
  1194 		}
       
  1195 	
       
  1196 	// Check if 3GP input data contains video stream
       
  1197 	TInt err = DoGetVideoProperties(); 
       
  1198 	if (err != KErrNone)
       
  1199 		{
       
  1200 		return err;
       
  1201 		}
       
  1202 	
       
  1203 	mp4_u32 numVideoFrame = 0;
       
  1204 	MP4Err mp4Err = MP4ParseGetNumberOfVideoFrames(iHandler, &numVideoFrame);
       
  1205 	if (mp4Err == MP4_OK)
       
  1206 		{
       
  1207 		aNum = numVideoFrame;
       
  1208 		}
       
  1209 	return SymbianOSError(mp4Err);
       
  1210 	}
       
  1211 
       
  1212 /**
       
  1213 This function gives the video sample entry index of the next video frame to be read.
       
  1214 
       
  1215 The smallest index value is 1.
       
  1216 
       
  1217 @param	aIndex	Returns the Visual Sample Entry index of the next video frame to be read.
       
  1218 
       
  1219 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1220 		KErrGeneral		if an error has no specific categorisation;
       
  1221 		KErrNotSupported	if the input does not contain video;		
       
  1222 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1223 */
       
  1224 EXPORT_C TInt C3GPParse::GetVideoSampleEntryIndex(TUint& aIndex) const
       
  1225 	{
       
  1226 	if (!iHandler)
       
  1227 		{
       
  1228 		return KErrNotReady;
       
  1229 		}
       
  1230 	
       
  1231 	// Check if 3GP input data contains video stream
       
  1232 	TInt err = DoGetVideoProperties(); 
       
  1233 	if (err != KErrNone)
       
  1234 		{
       
  1235 		return err;
       
  1236 		}
       
  1237 	
       
  1238 	mp4_u32 index = 0;
       
  1239 	MP4Err mp4Err = MP4ParseGetVideoSampleEntryIndex(iHandler, &index);
       
  1240 	if (mp4Err == MP4_OK)
       
  1241 		{
       
  1242 		aIndex = index;
       
  1243 		}
       
  1244 	return SymbianOSError(mp4Err);
       
  1245 	}
       
  1246 
       
  1247 /**
       
  1248 Returns video frame size.
       
  1249 
       
  1250 @param	aIndex	Index of video frame.
       
  1251 @param	aSize	Return the size of the video frame.
       
  1252 
       
  1253 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1254 		KErrGeneral		if an error has no specific categorisation;
       
  1255 		KErrNotSupported	if the input does not contain video;		
       
  1256 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1257 */
       
  1258 EXPORT_C TInt C3GPParse::GetVideoFrameSize(TUint aIndex, TUint& aSize) const
       
  1259 	{
       
  1260 	if (!iHandler)
       
  1261 		{
       
  1262 		return KErrNotReady;
       
  1263 		}
       
  1264 	
       
  1265 	// Check if 3GP input data contains video stream
       
  1266 	TInt err = DoGetVideoProperties(); 
       
  1267 	if (err != KErrNone)
       
  1268 		{
       
  1269 		return err;
       
  1270 		}
       
  1271 	
       
  1272 	mp4_u32 videoFrameSize = 0;
       
  1273 	MP4Err mp4Err = MP4ParseGetVideoFrameSize(iHandler, aIndex, &videoFrameSize);
       
  1274 	if (mp4Err == MP4_OK)
       
  1275 		{
       
  1276 		aSize = videoFrameSize;
       
  1277 		}
       
  1278 	return SymbianOSError(mp4Err);
       
  1279 	}
       
  1280 
       
  1281 /**
       
  1282 Returns video frame start time.
       
  1283 
       
  1284 @param	aIndex					Index of video frame.
       
  1285 @param	aTimeStampInMs			Result in milliseconds.
       
  1286 @param	aTimeStampInTimescale	Result is returned here.
       
  1287 
       
  1288 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1289 		KErrGeneral		if an error has no specific categorisation;
       
  1290 		KErrNotSupported	if the input does not contain video;		
       
  1291 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1292 */
       
  1293 EXPORT_C TInt C3GPParse::GetVideoFrameStartTime(TUint aIndex, TUint& aTimeStampInMs, TUint& aTimeStampInTimescale) const
       
  1294 	{
       
  1295 	if (!iHandler)
       
  1296 		{
       
  1297 		return KErrNotReady;
       
  1298 		}
       
  1299 	
       
  1300 	// Check if 3GP input data contains video stream
       
  1301 	TInt err = DoGetVideoProperties(); 
       
  1302 	if (err != KErrNone)
       
  1303 		{
       
  1304 		return err;
       
  1305 		}
       
  1306 	
       
  1307 	mp4_u32 timeStampInMs = 0;
       
  1308 	mp4_u32 timeStampInTimescale = 0;
       
  1309 	MP4Err mp4Err = MP4ParseGetVideoFrameStartTime(iHandler, aIndex, &timeStampInTimescale, &timeStampInMs);
       
  1310 	if (mp4Err == MP4_OK)
       
  1311 		{
       
  1312 		aTimeStampInMs = timeStampInMs;
       
  1313 		aTimeStampInTimescale = timeStampInTimescale;
       
  1314 		}
       
  1315 	return SymbianOSError(mp4Err);
       
  1316 	}
       
  1317 
       
  1318 /**
       
  1319 Checks if a video frame of with index aIndex exists.
       
  1320 
       
  1321 @param	aIndex		Index of video frame.
       
  1322 @param	aKeyFrame	Return ETrue if the video frame is a key frame.
       
  1323 
       
  1324 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1325 		KErrGeneral		if an error has no specific categorisation;
       
  1326 		KErrNotSupported	if the input does not contain video;		
       
  1327 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1328 */
       
  1329 EXPORT_C TInt C3GPParse::GetVideoFrameKeyType(TUint aIndex, TBool& aKeyFrame) const
       
  1330 	{
       
  1331 	if (!iHandler)
       
  1332 		{
       
  1333 		return KErrNotReady;
       
  1334 		}
       
  1335 	
       
  1336 	// Check if 3GP input data contains video stream
       
  1337 	TInt err = DoGetVideoProperties(); 
       
  1338 	if (err != KErrNone)
       
  1339 		{
       
  1340 		return err;
       
  1341 		}
       
  1342 	
       
  1343 	mp4_bool keyFrame = EFalse;
       
  1344 	MP4Err mp4Err = MP4ParseGetVideoFrameType(iHandler, aIndex, &keyFrame);
       
  1345 	if (mp4Err == MP4_OK)
       
  1346 		{
       
  1347 		aKeyFrame = keyFrame;
       
  1348 		}
       
  1349 	return SymbianOSError(mp4Err);
       
  1350 	}
       
  1351 
       
  1352 /**
       
  1353 This function gives the audio sample entry index of the next audio frame to be read.
       
  1354 
       
  1355 The smallest index value is 1. 
       
  1356 
       
  1357 @param	aIndex	Returns the Audio Sample Entry index of the next video frame to be read.
       
  1358 
       
  1359 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1360 		KErrGeneral		if an error has no specific categorisation;
       
  1361 		KErrNotSupported	if the input does not contain audio;		
       
  1362 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1363 */
       
  1364 EXPORT_C TInt C3GPParse::GetAudioSampleEntryIndex(TUint& aIndex) const
       
  1365 	{
       
  1366 	if (!iHandler)
       
  1367 		{
       
  1368 		return KErrNotReady;
       
  1369 		}
       
  1370 	
       
  1371 	// Check if 3GP input data contains audio stream
       
  1372 	TInt err = DoGetAudioProperties(); 
       
  1373 	if (err != KErrNone)
       
  1374 		{
       
  1375 		return err;
       
  1376 		}
       
  1377 	
       
  1378 	mp4_u32 audioSampleEntryIndex = 0;
       
  1379 	MP4Err mp4Err = MP4ParseGetAudioSampleEntryIndex(iHandler, &audioSampleEntryIndex);
       
  1380 	if (mp4Err == MP4_OK)
       
  1381 		{
       
  1382 		aIndex = audioSampleEntryIndex;
       
  1383 		}
       
  1384 	return SymbianOSError(mp4Err);
       
  1385 	}
       
  1386 
       
  1387 /**
       
  1388 This function provides the storage mode of 13K QCELP in 3G2 file. 
       
  1389 
       
  1390 In 3G2 files, QCELP can be registered to be stored in two ways:
       
  1391 	using the QCELP Sample Entry ('sqcp') Box or
       
  1392 	using the MPEG4 Audio Sample Description ('esds') Box.
       
  1393 
       
  1394 @param	aMode	Returns the QCELP storage mode.  See T3GPQcelpStorageMode.
       
  1395 
       
  1396 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1397 		KErrGeneral		if an error has no specific categorisation;
       
  1398 		KErrNotSupported	if the 3GP input data does not contain any QCELP audio stream;
       
  1399 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1400 */
       
  1401 EXPORT_C TInt C3GPParse::GetQcelpStorageMode(T3GPQcelpStorageMode& aMode) const
       
  1402 	{
       
  1403 	if (!iHandler)
       
  1404 		{
       
  1405 		return KErrNotReady;
       
  1406 		}
       
  1407 	
       
  1408 	// Check if 3GP input data contains any QCELP audio stream
       
  1409 	TInt err = DoGetAudioProperties();	
       
  1410 	if (err == KErrNone)
       
  1411 		{
       
  1412 		if (iAudioType != E3GPQcelp13K)
       
  1413 			{
       
  1414 			return KErrNotSupported;
       
  1415 			}
       
  1416 		}
       
  1417 	else
       
  1418 		{
       
  1419 		return err;
       
  1420 		}
       
  1421 
       
  1422 	mp4_u8 audioQcelpStorageMode = 0;
       
  1423 	MP4Err mp4Err = MP4ParseGetQCELPStorageMode(iHandler, &audioQcelpStorageMode);
       
  1424 	if (mp4Err == MP4_OK)
       
  1425 		{
       
  1426 		if (audioQcelpStorageMode == 1)
       
  1427 			{
       
  1428 			aMode = E3GPMP4AudioDescriptionBox;
       
  1429 			}
       
  1430 		else
       
  1431 			{
       
  1432 			aMode = E3GPQcelpSampleEntryBox;
       
  1433 			}
       
  1434 		}
       
  1435 	return SymbianOSError(mp4Err);
       
  1436 	}
       
  1437 
       
  1438 /**
       
  1439 This function provides the video level of the H263 video stream contained in the 3GP data. 
       
  1440 
       
  1441 @param	aLevel	Returns the H263 video level.
       
  1442 
       
  1443 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1444 		KErrGeneral		if an error has no specific categorisation;
       
  1445 		KErrNotSupported	if the 3GP input data does not contain any H263 video stream; 
       
  1446 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1447 */
       
  1448 EXPORT_C TInt C3GPParse::GetH263VideoLevel(TInt& aLevel) const
       
  1449 	{
       
  1450 	if (!iHandler)
       
  1451 		{
       
  1452 		return KErrNotReady;
       
  1453 		}
       
  1454 	
       
  1455 	// Check if 3GP input data contains any H263 video stream
       
  1456 	TInt err = DoGetVideoProperties();	
       
  1457 	if (err == KErrNone)
       
  1458 		{
       
  1459 		if (!(iVideoType == E3GPH263Profile0 || iVideoType == E3GPH263Profile3))
       
  1460 			{
       
  1461 			return KErrNotSupported;
       
  1462 			}
       
  1463 		}
       
  1464 	else
       
  1465 		{
       
  1466 		return err;
       
  1467 		}
       
  1468 	
       
  1469 	TVideoClipProperties videoClipProperties;
       
  1470 	MP4Err mp4Err = MP4ParseGetVideoClipProperties(iHandler, videoClipProperties);
       
  1471 	if (mp4Err == MP4_OK)
       
  1472 		{
       
  1473 		aLevel = videoClipProperties.iH263Level;
       
  1474 		}
       
  1475 	return SymbianOSError(mp4Err);
       
  1476 	}
       
  1477 
       
  1478 /**
       
  1479 Returns the needed size for memory buffer to store an atom of given type from user data atom (UDTA).
       
  1480 
       
  1481 @param	aType		Type of atom to be read from UDTA. Hex value of 4 chars representing atom type 
       
  1482 					defined in standard. For example, 0x7469746c is 'titl', title for the media atom.
       
  1483 @param	aLocation	Specifies the location of user information to be retrieved.  Refer to 
       
  1484 					T3GPUdtaLocation for supported values.
       
  1485 @param	aAtomIndex	Specifies the index of atom if UDTA contains multiple sub-atoms of the same 
       
  1486 					aUdtaAtomType to retrieve when supplied as input parameter.  Returns the 
       
  1487 					highest index of the matching sub-atom found in the specified location as 
       
  1488 					output parameter.
       
  1489 @param	aSize		This contains the needed size for memory buffer.
       
  1490 
       
  1491 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1492 		KErrGeneral		if an error has no specific categorisation;
       
  1493 		KErrNotFound	if UDTA or wanted sub-atom is not available in asked location;
       
  1494 		KErrAccessDenied	if cannot seek to UDTA atom location;
       
  1495 		KErrArgument	if asked aLocation is invalid;
       
  1496 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1497 
       
  1498 @panic C3GPParse	KErrArgument	if the location of user information is not in the range of T3GPUdtaLocation
       
  1499 */
       
  1500 EXPORT_C TInt C3GPParse::GetUserDataAtomSize(TUint32 aType, T3GPUdtaLocation aLocation, 
       
  1501 		TUint& aAtomIndex, TInt& aSize) const
       
  1502 	{
       
  1503 	if (!iHandler)
       
  1504 		{
       
  1505 		return KErrNotReady;
       
  1506 		}
       
  1507 	
       
  1508 	mp4_u32 userDataAtomSize = 0;
       
  1509 	mp4_u32 atomIndex = aAtomIndex;
       
  1510 	mp4_u32 type = aType;
       
  1511 	mp4_u8 location = UdtaLocation(aLocation);
       
  1512 	MP4Err mp4Err = MP4ParseGetUserDataAtom(iHandler, location, type, 
       
  1513 			NULL, userDataAtomSize, atomIndex);
       
  1514 	if ( mp4Err == MP4_OK  || mp4Err == MP4_OUTPUT_BUFFER_TOO_SMALL)
       
  1515 		{
       
  1516 		aSize = userDataAtomSize;
       
  1517 		aAtomIndex = atomIndex;
       
  1518 		mp4Err = MP4_OK;
       
  1519 		}
       
  1520 	return SymbianOSError(mp4Err);
       
  1521 	}
       
  1522 
       
  1523 /**
       
  1524 Retrieves an atom of given type from user data atom (UDTA) to the given buffer.
       
  1525 
       
  1526 The buffer returned stores an atom of structure that conforms to the definition of 
       
  1527 a "full box" as specified in ISO/IEC 14496-12:2003: "Information technology – Coding 
       
  1528 of audio-visual objects – Part 12: ISO base media file format."					
       
  1529 
       
  1530 For more information on user data atoms, see Section 8 – Asset Information of "3GPP 
       
  1531 TS 26.244 version 6.1.0 – 3GP file format (Rel 6)."
       
  1532 
       
  1533 @param	aType		Type of atom to be read from UDTA. Hex value of 4 chars representing atom type 
       
  1534 					defined in standard. For example, 0x7469746c is 'titl', title for the media atom.
       
  1535 @param	aLocation	Specifies the location of user information to be retrieved.  Refer to 
       
  1536 					T3GPUdtaLocation for supported values.
       
  1537 @param	aBuffer		The descriptor to store the requested user data atom.  
       
  1538 @param	aAtomIndex	Specifies the index of atom if UDTA contains multiple sub-atoms of the same 
       
  1539 					aUdtaAtomType to retrieve when supplied as input parameter.  Returns the 
       
  1540 					highest index of the matching sub-atom found in the specified location as 
       
  1541 					output parameter.  Only matching sub-atoms are counted when calculating the highest
       
  1542 					index.  
       
  1543 
       
  1544 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1545 		KErrGeneral		if an error has no specific categorisation;
       
  1546 		KErrNotFound	if UDTA or wanted sub-atom is not available in asked location;
       
  1547 		KErrAccessDenied	if cannot seek to UDTA atom location;
       
  1548 		KErrArgument	if asked aUdtaLocation is invalid;
       
  1549 		KErrOverflow	if the buffer to write atom to is too small. Use C3GPParse::GetUserDataAtomSize 
       
  1550 						to retrieve the proper size.
       
  1551 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
  1552 		KErr3gpLibMoreDataRequired	if if 3GP library needs more data before the requested 
       
  1553 						information can be returned.
       
  1554 
       
  1555 @panic C3GPParse	KErrArgument	if the location of user information is not in the range of T3GPUdtaLocation
       
  1556 */
       
  1557 EXPORT_C TInt C3GPParse::GetUserDataAtom(TUint32 aType, T3GPUdtaLocation aLocation, TDes8& aBuffer, TUint& aAtomIndex) const
       
  1558 	{
       
  1559 	if (!iHandler)
       
  1560 		{
       
  1561 		return KErrNotReady;
       
  1562 		}
       
  1563 	if (aBuffer.MaxLength() <= 0)
       
  1564 		{
       
  1565 		return KErrOverflow;
       
  1566 		}
       
  1567 	
       
  1568 	mp4_u32 userDataAtomSize = aBuffer.MaxLength();
       
  1569 	mp4_u32 atomIndex = aAtomIndex;
       
  1570 	mp4_u32 type = aType;
       
  1571 	mp4_u8 location = UdtaLocation(aLocation);
       
  1572 	MP4Err mp4Err = MP4ParseGetUserDataAtom(iHandler, location, type, 
       
  1573 			const_cast<mp4_u8*>(aBuffer.Ptr()), userDataAtomSize, atomIndex);	
       
  1574 	if ( mp4Err == MP4_OK )
       
  1575 		{
       
  1576 		aType = type;
       
  1577 		aBuffer.SetLength(userDataAtomSize);
       
  1578 		aAtomIndex = atomIndex;
       
  1579 		}
       
  1580 	return SymbianOSError(mp4Err);
       
  1581 	}
       
  1582 
       
  1583 /**
       
  1584 This function gets the next frame's dependency information from SDTP box.
       
  1585 
       
  1586 @param	aDependencies	Returns the next frame's dependency information. See T3GPFrameDependencies.
       
  1587 
       
  1588 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes. 
       
  1589 		KErrGeneral		if an error has no specific categorisation;
       
  1590 		KErrNotSupported	if the input does not contain video stream;
       
  1591 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open;
       
  1592 		KErr3gpLibMoreDataRequired	if if 3GP library needs more data before the requested 
       
  1593 						information can be returned.
       
  1594 */
       
  1595 EXPORT_C TInt C3GPParse::GetVideoFrameDependencies(T3GPFrameDependencies& aDependencies) const
       
  1596 	{
       
  1597 	if (!iHandler)
       
  1598 		{
       
  1599 		return KErrNotReady;
       
  1600 		}
       
  1601 	
       
  1602 	// Check if 3GP input data contains video stream
       
  1603 	TInt err = DoGetVideoProperties();	
       
  1604 	if (err != KErrNone)
       
  1605 		{
       
  1606 		return err;
       
  1607 		}
       
  1608 	
       
  1609 	mp4_u8 dependsOn;
       
  1610 	mp4_u8 isDependedOn;
       
  1611 	mp4_u8 hasRedundancy;	
       
  1612 	MP4Err mp4Err = MP4ParseNextVideoFrameDependencies(iHandler, &dependsOn, &isDependedOn, &hasRedundancy);
       
  1613 	if (mp4Err == MP4_OK)
       
  1614 		{
       
  1615 		switch (dependsOn)
       
  1616 			{
       
  1617 			case 1:
       
  1618 				aDependencies.iDependsOn = E3GPDependencyExists;
       
  1619 			break;
       
  1620 			case 2:
       
  1621 				aDependencies.iDependsOn = E3GPDependencyNone;
       
  1622 			break;
       
  1623 			case 0:
       
  1624 				aDependencies.iDependsOn = E3GPDependencyUnknown;
       
  1625 			break;
       
  1626 			default:
       
  1627 				Panic(KErrCorrupt);
       
  1628 			}
       
  1629 		
       
  1630 		switch (isDependedOn)
       
  1631 			{
       
  1632 			case 1:
       
  1633 				aDependencies.iIsDependedOn = E3GPDependencyExists;
       
  1634 			break;
       
  1635 			case 2:
       
  1636 				aDependencies.iIsDependedOn = E3GPDependencyNone;
       
  1637 			break;
       
  1638 			case 0:
       
  1639 				aDependencies.iIsDependedOn = E3GPDependencyUnknown;
       
  1640 			break;
       
  1641 			default:
       
  1642 				Panic(KErrCorrupt);
       
  1643 			}
       
  1644 		
       
  1645 		switch (hasRedundancy)
       
  1646 			{
       
  1647 			case 1:
       
  1648 				aDependencies.iHasRedundancy = E3GPRedundancyExists;
       
  1649 			break;
       
  1650 			case 2:
       
  1651 				aDependencies.iHasRedundancy = E3GPRedundancyNone;
       
  1652 			break;
       
  1653 			case 0:
       
  1654 				aDependencies.iHasRedundancy = E3GPRedundancyUnknown;
       
  1655 			break;
       
  1656 			default:
       
  1657 				Panic(KErrCorrupt);
       
  1658 			}
       
  1659 		}
       
  1660 	return SymbianOSError(mp4Err);
       
  1661 	}
       
  1662 
       
  1663 /**
       
  1664 This function gets frame properties, from aStartIndex for a count of aNumberOfFrames frames.
       
  1665 
       
  1666 Properties obtained are start time, frame type, and frame size, stored in the T3GPFrameInfoParameters 
       
  1667 struct.
       
  1668 
       
  1669 @param	aStartIndex		Index to start getting info for the array.
       
  1670 @param	aNumberOfFrames	Number of frames to retrieve frame info.
       
  1671 @param	aArray			An array of T3GPFrameInfoParameters struct to store video frame properties.  
       
  1672 						The input array will be flushed of all existing elements before use.
       
  1673 
       
  1674 @return	KErrNone 		if successful.  Otherwise, returns one of the system wide error codes.
       
  1675 		KErrGeneral		if an error has no specific categorisation;
       
  1676 		KErrNotSupported	if the input does not contain video stream;		
       
  1677 		KErrNoMemory	if an attempt to allocate memory has failed;
       
  1678 		KErrAccessDenied	if opening file has failed;		
       
  1679 		KErrNotReady	if the parser has not yet been initialised; See C3GPParse::Open.
       
  1680 */
       
  1681 EXPORT_C TInt C3GPParse:: GetVideoFrameProperties(TUint aStartIndex, TUint aNumberOfFrames, 
       
  1682 		RArray<T3GPFrameInfoParameters>& aArray) const
       
  1683 	{
       
  1684 	if (!iHandler)
       
  1685 		{
       
  1686 		return KErrNotReady;
       
  1687 		}
       
  1688 	
       
  1689 	// Check if 3GP input data contains video stream
       
  1690 	TInt err = DoGetVideoProperties();	
       
  1691 	if (err != KErrNone)
       
  1692 		{
       
  1693 		return err;
       
  1694 		}
       
  1695 	
       
  1696 	// Check if the input parameters are valid before retrieving video frame properties.
       
  1697 	TUint totalNumOfVideoFrames;
       
  1698 	err = GetNumberOfVideoFrames(totalNumOfVideoFrames);
       
  1699 	if (err != KErrNone)
       
  1700 		{
       
  1701 		return err;
       
  1702 		}
       
  1703 	
       
  1704 	if (aStartIndex >= totalNumOfVideoFrames || aNumberOfFrames > totalNumOfVideoFrames)	
       
  1705 		{
       
  1706 		return KErrGeneral;
       
  1707 		}
       
  1708 	
       
  1709 	TFrameInfoParameters* infoArray = new TFrameInfoParameters[aNumberOfFrames];
       
  1710 	
       
  1711 	if (!infoArray)
       
  1712 		{
       
  1713 		return KErrNoMemory;
       
  1714 		}
       
  1715 
       
  1716 	mp4_u32 startIndex = aStartIndex;
       
  1717 	mp4_u32 numberOfFrames = aNumberOfFrames;
       
  1718 	MP4Err mp4Err = MP4GetVideoFrameProperties(iHandler, startIndex, numberOfFrames, infoArray);
       
  1719 
       
  1720 	if ( mp4Err == MP4_OK )
       
  1721 		{
       
  1722 		aArray.Reset();
       
  1723 		T3GPFrameInfoParameters infoParams; 
       
  1724 		
       
  1725 		for (TInt i=0; i<aNumberOfFrames; ++i)
       
  1726 			{
       
  1727 			infoParams.iSize = infoArray[i].iSize;
       
  1728 			infoParams.iStartTime = infoArray[i].iStartTime;
       
  1729 			infoParams.iIsRandomAccessPoint = infoArray[i].iType;
       
  1730 			err = aArray.Append(infoParams);
       
  1731 			if (err != KErrNone)
       
  1732 				{
       
  1733 				delete [] infoArray;
       
  1734 				infoArray = NULL;
       
  1735 				return err;
       
  1736 				}
       
  1737 			}		
       
  1738 		}
       
  1739 	else
       
  1740 		{
       
  1741 		err = SymbianOSError(mp4Err);
       
  1742 		}
       
  1743 	delete [] infoArray;
       
  1744 	infoArray = NULL;
       
  1745 	return err;
       
  1746 	}
       
  1747 
       
  1748 /**
       
  1749 This function reads the current video frame from an input file and returns it to the caller asynchronously.  
       
  1750 The current position of video stream will be moved forward.
       
  1751 
       
  1752 This function is not supported when the parser is in buffer mode.
       
  1753 
       
  1754 C3GPParse::CancelReadFrame can be used to cancel an outstanding asynchronous frame read request.
       
  1755 
       
  1756 Note:  Only one asynchronous parse audio or video frame(s) operation can be ongoing at any given time.
       
  1757 
       
  1758 Upon completion, successfully or otherwise, the callback function M3GPParseCallback::VideoFrameAvailable is called.
       
  1759 
       
  1760 @param	aCallback	Reference to class derived from M3GPAsyncObserver designed to receive notification of 
       
  1761 					asynchronous event completion.
       
  1762 @param	aBuffer		The descriptor to store the video frames.
       
  1763 */
       
  1764 EXPORT_C void C3GPParse::ReadVideoFrame(M3GPParseCallback& aCallback, TDes8& aBuffer)
       
  1765 	{
       
  1766 	if (!iHandler)
       
  1767 		{
       
  1768 		aCallback.VideoFrameAvailable(KErrNotReady, EFalse, 0, 0);
       
  1769 		return;
       
  1770 		}
       
  1771 	if (aBuffer.MaxLength() <= 0)
       
  1772 		{
       
  1773 		aCallback.VideoFrameAvailable(KErrOverflow, EFalse, 0, 0);
       
  1774 		return;
       
  1775 		}
       
  1776 	if (iAsyncReadBuffer)
       
  1777 		{
       
  1778 		aCallback.VideoFrameAvailable(KErrInUse, EFalse, 0, 0);
       
  1779 		return;
       
  1780 		}
       
  1781 	
       
  1782 	// Check if 3GP input data contains video stream
       
  1783 	TInt err = DoGetVideoProperties();	
       
  1784 	if (err != KErrNone)
       
  1785 		{
       
  1786 		aCallback.VideoFrameAvailable(err, EFalse, 0, 0);
       
  1787 		return;
       
  1788 		}
       
  1789 	
       
  1790 	iCallback = &aCallback;
       
  1791 	mp4_u32 bufferSize = aBuffer.MaxLength();
       
  1792 	MP4Err mp4Err = MP4ParseReadVideoFrameAsync(iHandler, this, 
       
  1793 			const_cast<mp4_u8*>(aBuffer.Ptr()), &bufferSize);	
       
  1794 	if (mp4Err != MP4_OK)
       
  1795 		{
       
  1796 		aCallback.VideoFrameAvailable(SymbianOSError(mp4Err), EFalse, 0, 0);
       
  1797 		}
       
  1798 	else
       
  1799 		{
       
  1800 		// MP4ParseReadVideoFrameAsync success. Store aBuffer since its length has
       
  1801 		// not been set.
       
  1802 		iAsyncReadBuffer = &aBuffer;
       
  1803 		}
       
  1804 	}
       
  1805 
       
  1806 /**
       
  1807 This function reads the audio frames that are stored in the current audio sample from the input 
       
  1808 file and returns them to the caller asynchronously.  The current position of audio stream 
       
  1809 will be moved forward. 
       
  1810 
       
  1811 This function is not supported when the parser is in buffer mode.
       
  1812 
       
  1813 C3GPParse::CancelReadFrame can be used to cancel an outstanding asynchronous frame read request.
       
  1814 
       
  1815 Note:  Only one asynchronous parse audio or video frame(s) operation can be ongoing at any given time.
       
  1816 
       
  1817 Upon completion, successfully or otherwise, the callback function M3GPParseCallback::AudioFramesAvailable is called.
       
  1818 
       
  1819 @param	aCallback	Reference to class derived from M3GPAsyncObserver designed to receive notification of 
       
  1820 					asynchronous event completion.
       
  1821 @param	aBuffer		The descriptor to store the audio frames.
       
  1822 */
       
  1823 EXPORT_C void C3GPParse::ReadAudioFrames(M3GPParseCallback& aCallback, TDes8& aBuffer)
       
  1824 	{
       
  1825 	if (!iHandler)
       
  1826 		{
       
  1827 		aCallback.AudioFramesAvailable(KErrNotReady, 0, 0, 0);
       
  1828 		return;
       
  1829 		}
       
  1830 	if (aBuffer.MaxLength() <= 0)
       
  1831 		{
       
  1832 		aCallback.AudioFramesAvailable(KErrOverflow, 0, 0, 0);
       
  1833 		return;
       
  1834 		}
       
  1835 	if (iAsyncReadBuffer)
       
  1836 		{
       
  1837 		aCallback.AudioFramesAvailable(KErrInUse, 0, 0, 0);
       
  1838 		return;
       
  1839 		}
       
  1840 	
       
  1841 	// Check if 3GP input data contains audio stream
       
  1842 	TInt err = DoGetAudioProperties();	
       
  1843 	if (err != KErrNone)
       
  1844 		{
       
  1845 		aCallback.AudioFramesAvailable(err, 0, 0, 0);
       
  1846 		return;
       
  1847 		}
       
  1848 	
       
  1849 	iCallback = &aCallback;
       
  1850 	mp4_u32 bufferSize = aBuffer.MaxLength(); 
       
  1851 	MP4Err mp4Err = MP4ParseReadAudioFramesAsync(iHandler, this, 
       
  1852 			const_cast<mp4_u8*>(aBuffer.Ptr()), &bufferSize);	
       
  1853 	if (mp4Err != MP4_OK)
       
  1854 		{
       
  1855 		aCallback.AudioFramesAvailable(SymbianOSError(mp4Err), 0, 0, 0);
       
  1856 		}
       
  1857 	else
       
  1858 		{
       
  1859 		// MP4ParseReadAudioFramesAsync success. Store aBuffer since its length has
       
  1860 		// not been set.
       
  1861 		iAsyncReadBuffer = &aBuffer;
       
  1862 		}
       
  1863 	}
       
  1864 
       
  1865 /**
       
  1866 This function cancels the outstanding asynchronous read audio/video frame request. 
       
  1867 
       
  1868 No callback function will be called.
       
  1869 
       
  1870 Note:  As only one asynchronous parse audio or video frame(s) operation can be ongoing at any given time, 
       
  1871 this function can be used to cancel audio or video read request.
       
  1872 */
       
  1873 EXPORT_C void C3GPParse::CancelReadFrame()
       
  1874 	{
       
  1875 	if (!iHandler)
       
  1876 		{
       
  1877 		return;
       
  1878 		}
       
  1879 	if (iAsyncReadBuffer)
       
  1880 		{
       
  1881 		MP4CancelReadFrame(iHandler);
       
  1882 		iAsyncReadBuffer = NULL;
       
  1883 		iCallback = NULL;
       
  1884 		}	
       
  1885 	}
       
  1886 
       
  1887 // Receive asynchronous parse video frames operation completion notification.
       
  1888 void C3GPParse::M3GPMP4LibVideoFrameAvailable(MP4Err aError, mp4_u32 aFrameSize, mp4_u32 aTimeStamp, 
       
  1889 		mp4_bool aKeyFrame, mp4_u32 aTimestamp2)
       
  1890 	{	
       
  1891 	// Check if there is an outstanding asynchronous request
       
  1892 	if (iAsyncReadBuffer)
       
  1893 		{
       
  1894 		if (aError == MP4_OK)
       
  1895 			{
       
  1896 			// Set the buffer length for the asynchronous read video frame
       
  1897 			iAsyncReadBuffer->SetLength(aFrameSize);
       
  1898 			}
       
  1899 		iAsyncReadBuffer = NULL;
       
  1900 		// Parser can send out the callback to the client
       
  1901 		TBool keyFrame = aKeyFrame;
       
  1902 		TUint timeStampInMs = aTimeStamp;
       
  1903 		TUint timeStampInTimescale = aTimestamp2;	
       
  1904 		iCallback->VideoFrameAvailable(SymbianOSError(aError), keyFrame, timeStampInMs, timeStampInTimescale);
       
  1905 		}
       
  1906 
       
  1907 	iCallback = NULL;
       
  1908 	}
       
  1909 
       
  1910 // Receive asyncronous parse audio frames operation completion notification.
       
  1911 void C3GPParse::M3GPMP4LibAudioFramesAvailable(MP4Err aError, mp4_u32 aAudioSize, mp4_u32 aTimeStamp, 
       
  1912 		mp4_u32 aReturnedFrames, mp4_u32 aTimestamp2)
       
  1913 	{	
       
  1914 	// Check if there is an outstanding asynchronous request	
       
  1915 	if (iAsyncReadBuffer)
       
  1916 		{
       
  1917 		if (aError == MP4_OK)
       
  1918 			{
       
  1919 			// Set the buffer length for the asynchronous read audio frame
       
  1920 			iAsyncReadBuffer->SetLength(aAudioSize);
       
  1921 			}
       
  1922 		iAsyncReadBuffer = NULL;
       
  1923 		// Parser can send out the callback to the client
       
  1924 		TUint returnedFrames = aReturnedFrames;
       
  1925 		TUint timeStampInMs = aTimeStamp;
       
  1926 		TUint timeStampInTimescale = aTimestamp2;
       
  1927 		iCallback->AudioFramesAvailable(SymbianOSError(aError), returnedFrames, timeStampInMs, timeStampInTimescale);	
       
  1928 		}
       
  1929 
       
  1930 	iCallback = NULL;
       
  1931 	}
       
  1932 
       
  1933 // Helper function to convert c style error code to Symbian OS standard error code
       
  1934 TInt C3GPParse::SymbianOSError(MP4Err aError) const
       
  1935 	{
       
  1936 	TInt error = KErrNone;
       
  1937 	
       
  1938 	switch (aError)
       
  1939 		{
       
  1940 		case (MP4_OK):
       
  1941 		break;
       
  1942 		case (MP4_ERROR):
       
  1943 			error = KErrGeneral;
       
  1944 		break;
       
  1945 		case (MP4_OUT_OF_MEMORY):
       
  1946 			error = KErrNoMemory;
       
  1947 		break;
       
  1948 		case (MP4_NOT_AVAILABLE):
       
  1949 			error = KErr3gpLibMoreDataRequired;
       
  1950 		break;
       
  1951 		case (MP4_FILE_MODE):
       
  1952 		case (MP4_NOT_STREAMABLE):
       
  1953 		case (MP4_NO_VIDEO):
       
  1954 		case (MP4_NO_AUDIO):
       
  1955 			error = KErrNotSupported;
       
  1956 		break;
       
  1957 		case (MP4_BUFFER_TOO_SMALL):
       
  1958 		case (MP4_OUTPUT_BUFFER_TOO_SMALL):
       
  1959 			error = KErrOverflow;
       
  1960 		break;
       
  1961 		case (MP4_END_OF_VIDEO):
       
  1962 			error = KErrEof;
       
  1963 		break;
       
  1964 		case (MP4_CANT_SEEK):
       
  1965 		case (MP4_NO_FRAME):
       
  1966 		case (MP4_NO_REQUESTED_FRAME):
       
  1967 		case (MP4_UDTA_NOT_FOUND):
       
  1968 			error = KErrNotFound;
       
  1969 		break;
       
  1970 		case (MP4_FILE_ERROR):
       
  1971 			error = KErrAccessDenied;
       
  1972 		break;
       
  1973 		case (MP4_INVALID_INPUT_STREAM):
       
  1974 			error = KErrCorrupt;
       
  1975 		break;
       
  1976 		case (MP4_INVALID_TYPE):
       
  1977 			error = KErrArgument;
       
  1978 		break;
       
  1979 		default:
       
  1980 		// Mapped all possible errors returned by the MP4_library. Anything else should NOT happen
       
  1981 			Panic(KErrArgument);
       
  1982 		}
       
  1983 	return error;
       
  1984 	}
       
  1985 
       
  1986 // Help function to get video properties
       
  1987 TInt C3GPParse::DoGetVideoProperties() const
       
  1988 	{
       
  1989 	if (!iVideoPropertiesSaved || iVideoError == KErr3gpLibMoreDataRequired)
       
  1990 		{
       
  1991 		MP4Err mp4Err = MP4_OK;
       
  1992 		mp4_u32 length = 0;
       
  1993 		mp4_u32 type = 0;
       
  1994 		mp4_u32 width = 0;
       
  1995 		mp4_u32 height = 0;
       
  1996 		mp4_u32 timeScale = 0;
       
  1997 		mp4_double frameRate = 0;
       
  1998 
       
  1999 		mp4Err = MP4ParseRequestVideoDescription(iHandler, &length, &frameRate, &type, &width, &height, &timeScale);
       
  2000 		iVideoPropertiesSaved = ETrue;
       
  2001 		if (mp4Err == MP4_OK)
       
  2002 			{
       
  2003 			iVideoType = WrapperVideoType(type);
       
  2004 			if (iVideoType == E3GPNoVideo)
       
  2005 				{
       
  2006 				iVideoError = KErrNotSupported;
       
  2007 				return KErrNotSupported;
       
  2008 				}
       
  2009 			iVideoLength = length;
       
  2010 			iVideoMp4Type = type; // Type of video stream			
       
  2011 			iVideoSize.iWidth = width;
       
  2012 			iVideoSize.iHeight = height;
       
  2013 			iVideoTimeScale = timeScale;
       
  2014 			iVideoFrameRate = frameRate;	
       
  2015 			}
       
  2016 		iVideoError = SymbianOSError(mp4Err);
       
  2017 		}
       
  2018 	return iVideoError;
       
  2019 	}
       
  2020 
       
  2021 // Help function to get audio properties
       
  2022 TInt C3GPParse::DoGetAudioProperties() const
       
  2023 	{
       
  2024 	if (!iAudioPropertiesSaved || iAudioError == KErr3gpLibMoreDataRequired)
       
  2025 		{
       
  2026 		MP4Err mp4Err = MP4_OK;
       
  2027 		mp4_u32 audioLength = 0;
       
  2028 		mp4_u32 audioType = 0;
       
  2029 		mp4_u32 averateBitRate = 0;
       
  2030 		mp4_u32 timeScale = 0;
       
  2031 		mp4_u8 framesPerSample = 0;
       
  2032 		
       
  2033 		mp4Err = MP4ParseRequestAudioDescription(iHandler, &audioLength, &audioType, 
       
  2034 				&framesPerSample, &timeScale, &averateBitRate);
       
  2035 		iAudioPropertiesSaved = ETrue;
       
  2036 		if (mp4Err == MP4_OK)
       
  2037 			{
       
  2038 			iAudioLength = audioLength;
       
  2039 			iAudioMp4Type = audioType; // Type of audio stream
       
  2040 			iAudioType = WrapperAudioType(audioType);
       
  2041 			iAudioFramesPerSample = framesPerSample;
       
  2042 			iAudioAvgBitRate = averateBitRate;
       
  2043 			iAudioTimeScale = timeScale;
       
  2044 			}
       
  2045 		iAudioError = SymbianOSError(mp4Err);
       
  2046 		}
       
  2047 	return iAudioError;
       
  2048 	}
       
  2049 
       
  2050 // Help function to get stream properties
       
  2051 TInt C3GPParse::DoGetStreamProperties() const
       
  2052 	{
       
  2053 	if (!iStreamPropertiesSaved || iStreamError == KErr3gpLibMoreDataRequired)
       
  2054 		{
       
  2055 		MP4Err mp4Err = MP4_OK;
       
  2056 		mp4_u32 streamSize = 0;
       
  2057 		mp4_u32 streamAvgBitRate;
       
  2058 		mp4Err = MP4ParseRequestStreamDescription(iHandler,&streamSize, &streamAvgBitRate);
       
  2059 		iStreamPropertiesSaved = ETrue;
       
  2060 		if (mp4Err == MP4_OK)
       
  2061 			{
       
  2062 			iStreamSize = streamSize;
       
  2063 			iStreamAvgBitRate = streamAvgBitRate;
       
  2064 			}
       
  2065 		iStreamError = SymbianOSError(mp4Err);	
       
  2066 		}
       
  2067 	return iStreamError;
       
  2068 	}
       
  2069 
       
  2070 // Helper function to map Mp4 enum type to T3GPVideoType for video
       
  2071 T3GPVideoType C3GPParse::WrapperVideoType(TUint aType) const
       
  2072 	{
       
  2073 	T3GPVideoType videoType = E3GPNoVideo;
       
  2074 	switch (aType)
       
  2075 		{
       
  2076 		case (MP4_TYPE_MPEG4_VIDEO):
       
  2077 			videoType = E3GPMpeg4Video;
       
  2078 		break;
       
  2079 		case (MP4_TYPE_H263_PROFILE_0):
       
  2080 			videoType = E3GPH263Profile0;
       
  2081 		break;
       
  2082 		case (MP4_TYPE_H263_PROFILE_3):
       
  2083 			videoType = E3GPH263Profile3;
       
  2084 		break;
       
  2085 		case (MP4_TYPE_AVC_PROFILE_BASELINE):
       
  2086 			videoType = E3GPAvcProfileBaseline;
       
  2087 		break;
       
  2088 		case (MP4_TYPE_AVC_PROFILE_MAIN):
       
  2089 			videoType = E3GPAvcProfileMain;
       
  2090 		break;
       
  2091 		case (MP4_TYPE_AVC_PROFILE_EXTENDED):
       
  2092 			videoType = E3GPAvcProfileExtended;
       
  2093 		break;
       
  2094 		
       
  2095 		case (MP4_TYPE_AVC_PROFILE_HIGH):
       
  2096 			videoType = E3GPAvcProfileHigh;
       
  2097 		break;
       
  2098 		case MP4_TYPE_NONE:
       
  2099 		break;
       
  2100 		default:
       
  2101 			Panic(KErrCorrupt); // This should not happen.
       
  2102 		break;
       
  2103 		}
       
  2104 	return videoType;
       
  2105 	}
       
  2106 
       
  2107 // Helper function to map Mp4 enum type to T3GPAudioType for audio
       
  2108 T3GPAudioType C3GPParse::WrapperAudioType(TUint aType) const
       
  2109 	{
       
  2110 	T3GPAudioType audioType = E3GPNoAudio;
       
  2111 	switch (aType)
       
  2112 		{
       
  2113 		case (MP4_TYPE_MPEG4_AUDIO):
       
  2114 			audioType = E3GPMpeg4Audio;
       
  2115 		break;
       
  2116 		case (MP4_TYPE_AMR_NB):
       
  2117 			audioType = E3GPAmrNB;
       
  2118 		break;
       
  2119 		case (MP4_TYPE_AMR_WB):
       
  2120 			audioType = E3GPAmrWB;
       
  2121 		break;
       
  2122 		case (MP4_TYPE_QCELP_13K):
       
  2123 			audioType = E3GPQcelp13K;
       
  2124 		break;
       
  2125 		default:
       
  2126 			Panic(KErrCorrupt); // This should not happen.
       
  2127 		}
       
  2128 	return audioType;
       
  2129 	}
       
  2130 
       
  2131 // Helper function to map enum type of the location of the user data in the file
       
  2132 mp4_u8 C3GPParse::UdtaLocation(T3GPUdtaLocation aLocation) const
       
  2133 	{
       
  2134 	mp4_u8 location  = MP4_UDTA_NONE;
       
  2135 	
       
  2136 	switch (aLocation )
       
  2137 		{
       
  2138 		case (E3GPUdtaMoov):
       
  2139 			location = MP4_UDTA_MOOV;
       
  2140 		break;
       
  2141 		case (E3GPUdtaVideoTrak):
       
  2142 			location = MP4_UDTA_VIDEOTRAK;
       
  2143 		break;
       
  2144 		case (E3GPUdtaAudioTrak):
       
  2145 			location = MP4_UDTA_AUDIOTRAK;
       
  2146 		break;
       
  2147 		default:
       
  2148 			Panic(KErrArgument);
       
  2149 		}
       
  2150 	return location;
       
  2151 	}
       
  2152 
       
  2153 
       
  2154 void C3GPParse::Panic(TInt aPanic)
       
  2155 	// Panic client
       
  2156 	{
       
  2157 	_LIT(K3GPParsePanicName, "C3GPParse");
       
  2158 	User::Panic(K3GPParsePanicName, aPanic);
       
  2159 	}