First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <c3gplibrary.h>
19 Creates an instance of a 3GP Parser for reading 3GP/3G2/MP4 data using default buffer size.
21 The default value for read buffer size is 8k.
23 @return A pointer to the newly created 3gp parse object.
25 @leave KErrNoMemory Out of memory.
27 EXPORT_C C3GPParse* C3GPParse::NewL()
29 C3GPParse* self = new (ELeave) C3GPParse();
34 Creates an instance of a 3GP Parser for reading 3GP/3G2/MP4 data, and sets the
35 internal file read buffer size.
37 @param aReadBufferSize Size of file read buffer.
39 @return A pointer to the newly created 3gp parse object.
41 @leave KErrNoMemory Out of memory.
42 @leave KErrGeneral General error.
44 @panic C3GPParse KErrArgument if size of file read buffer is not greater than 0.
46 EXPORT_C C3GPParse* C3GPParse::NewL(TInt aReadBufferSize)
48 __ASSERT_ALWAYS((aReadBufferSize > 0), Panic(KErrArgument));
49 C3GPParse* self = new (ELeave) C3GPParse(aReadBufferSize);
53 // First phase constructor
54 C3GPParse::C3GPParse(TInt aReadBufferSize) :
55 iReadBufferSize(aReadBufferSize),
56 iDuplicateFileHandleCreated(EFalse),
57 iVideoType(E3GPNoVideo),
58 iAudioType(E3GPNoAudio)
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.
66 @see C3GPParse::InsertData
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.
74 EXPORT_C TInt C3GPParse::Open()
81 return SymbianOSError(MP4ParseOpen(&iHandler, NULL));
85 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a file.
87 @param aFilename A full path name of the file containing the data.
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.
97 EXPORT_C TInt C3GPParse::Open(const TDesC& aFilename)
103 if (aFilename.Length() <= 0)
105 return KErrUnderflow;
108 // Create a zero terminated version of the file name
110 TInt err = fileName.Create(aFilename.Length() + 1);
113 fileName.Copy(aFilename);
114 mp4_u16* mp4FileName = const_cast<mp4_u16*>(fileName.PtrZ());
115 MP4Err mp4Err = MP4ParseOpen(&iHandler, reinterpret_cast<MP4FileName>(mp4FileName));
117 if (mp4Err == MP4_OK)
119 // Set composing related values to 0.
120 mp4Err = MP4SetCustomFileBufferSizes(iHandler, 0, 0, iReadBufferSize);
121 if (mp4Err != MP4_OK)
127 err = SymbianOSError(mp4Err);
134 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a file.
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.
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.
144 EXPORT_C TInt C3GPParse::Open(const RFile& aFile)
147 if (!iDuplicateFileHandleCreated)
149 iDuplicateFileHandleCreated = ETrue;
151 err = iFile.Duplicate(aFile);
161 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a file.
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.
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.
171 EXPORT_C TInt C3GPParse::Open(const RFile64& aFile)
178 const RFile64* file = &aFile;
179 MP4Err mp4Err = MP4ParseOpenFileHandle64(&iHandler, (const_cast<RFile64*>(file)));
180 if (mp4Err == MP4_OK)
182 // Set composing related values to 0.
183 mp4Err = MP4SetCustomFileBufferSizes(iHandler, 0, 0, iReadBufferSize);
184 if (mp4Err != MP4_OK)
191 return SymbianOSError(mp4Err);
195 This function initialises the 3GP Parser for reading 3GP/3G2/MP4 data from a CAF object.
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.
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.
205 EXPORT_C TInt C3GPParse::Open(const ContentAccess::CData& aData)
212 MP4Err mp4Err = MP4ParseOpenCAF(&iHandler, const_cast<ContentAccess::CData*>(&aData));
214 if (mp4Err == MP4_OK)
216 // Set composing related values to 0.
217 mp4Err = MP4SetCustomFileBufferSizes(iHandler, 0, 0, iReadBufferSize);
218 if (mp4Err != MP4_OK)
225 return SymbianOSError(mp4Err);
229 Destructor. Deletes all objects.
231 EXPORT_C C3GPParse::~C3GPParse()
233 Complete(); // Ignore the error
237 This function completes the parsing operation.
239 If C3GPParse::Complete is called before the parse is initialised, it will be ignored and KErrNone is
242 The parser can be reused again after this call, following another call to C3GPParse::Open to
243 re-initialise the parser.
245 @return KErrNone if successful. Otherwise, returns one of the system wide error codes.
246 KErrGeneral if an error has no specific categorisation;
248 EXPORT_C TInt C3GPParse::Complete()
250 MP4Err mp4Err = MP4_OK;
253 mp4Err = MP4ParseClose(iHandler);
256 if (iAsyncReadBuffer)
261 // Always reset the class member data even MP4ParseClose returns error
263 return SymbianOSError(mp4Err);
266 // Helper function to reset class member data.
267 void C3GPParse::Reset()
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;
282 iDuplicateFileHandleCreated = EFalse;
287 This function inserts MP4/3GP/3G2 data into the parser.
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.
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.
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.
302 @param aBuffer The descriptor containing the data to be inserted.
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.
309 EXPORT_C TInt C3GPParse::InsertData(const TDesC8& aBuffer)
316 return SymbianOSError(MP4ParseWriteData(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), aBuffer.Length()));
320 This function returns the parameters describing the video stream.
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.
326 The aFrameRate parameter refers to the frame rate of the original video material.
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.
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.
343 EXPORT_C TInt C3GPParse::GetVideoProperties(T3GPVideoType& aType, TUint& aLength, TReal& aFrameRate,
344 TUint& aAvgBitRate, TSize& aSize, TUint& aTimeScale) const
351 TInt err = DoGetVideoProperties();
355 aLength = iVideoLength;
357 aFrameRate = iVideoFrameRate;
358 aSize.iWidth = iVideoSize.iWidth;
359 aSize.iHeight = iVideoSize.iHeight;
360 aTimeScale = iVideoTimeScale;
367 // Get average bit rate of the stream in bps
368 err = DoGetStreamProperties();
374 // Video average bit rate is calculated from GetStreamDescription’s aAvgBitRate substructs Audio’s aAvgBitRate
375 // GetAudioProperties has not been called
376 err = DoGetAudioProperties();
379 aAvgBitRate = iStreamAvgBitRate - iAudioAvgBitRate;
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;
393 This function returns the parameters describing the audio stream.
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
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.
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.
413 EXPORT_C TInt C3GPParse::GetAudioProperties(T3GPAudioType& aType, TUint& aLength, TInt& aFramesPerSample,
414 TUint& aAvgBitRate, TUint& aTimeScale) const
421 TInt err = DoGetAudioProperties();
425 aLength = iAudioLength;
427 aFramesPerSample = iAudioFramesPerSample;
428 aAvgBitRate = iAudioAvgBitRate;
429 aTimeScale = iAudioTimeScale;
430 iAudioPropertiesSaved = ETrue;
437 This function returns the parameters that describe the contents of the input file or buffer.
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
443 @param aSize Length of the stream in bytes.
444 @param aAvgBitRate Average bit rate of the stream in bps.
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.
453 EXPORT_C TInt C3GPParse::GetContainerProperties(TUint& aSize, TUint& aAvgBitRate) const
460 TInt err = DoGetStreamProperties();
464 aAvgBitRate = iStreamAvgBitRate;
471 This function returns the number of bytes that the library instance has in its allocated buffers.
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
477 @see C3GPParse::InsertData.
479 @param aNum Number of allocated bytes in the library.
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.
486 EXPORT_C TInt C3GPParse::GetNumBufferedBytes(TInt& aNum) const
493 mp4_u32 numBytes = 0;
494 MP4Err mp4Err = MP4ParseGetBufferedBytes(iHandler, &numBytes);
497 return SymbianOSError(mp4Err);
501 This function returns the type of the next audio/video frame in the stream.
503 This function has no effect on the parser’s current position.
505 @param aType Type of the next frame. Refer to the definition of T3GPFrameType for all possible values.
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.
515 EXPORT_C TInt C3GPParse::GetFrameType(T3GPFrameType& aType) const
521 mp4_u32 frameType = 0;
522 MP4Err mp4Err = MP4ParseNextFrameType(iHandler, &frameType);
523 if (mp4Err == MP4_OK)
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
537 else if (frameType == MP4_TYPE_MPEG4_AUDIO || frameType == MP4_TYPE_AMR_NB ||
538 frameType == MP4_TYPE_AMR_WB || frameType == MP4_TYPE_QCELP_13K)
544 // This should not happen
548 return SymbianOSError(mp4Err);
552 This function returns the size of the immediate next video frame based on the current
553 position of the parser.
555 Calling this function does not change the current position of the parser.
557 @param aSize Size of the next video frame in bytes.
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.
567 EXPORT_C TInt C3GPParse::GetVideoFrameSize(TUint& aSize) const
574 // Check if 3GP input data contains video stream
575 TInt err = DoGetVideoProperties();
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)
589 return SymbianOSError(mp4Err);
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.
596 This function has no effect on the parser’s current position.
598 @param aSize Size of the next audio sample in bytes.
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.
608 EXPORT_C TInt C3GPParse::GetAudioFramesSize(TUint& aSize) const
615 // Check if 3GP input data contains audio stream
616 TInt err = DoGetAudioProperties();
622 // audio type from 3GP file header has been saved. Directely use iAudioMp4Type as input
623 mp4_u32 frameSize = 0;
625 MP4Err mp4Err = MP4ParseNextFrameSize(iHandler, iAudioMp4Type, &frameSize);
626 if (mp4Err == MP4_OK)
631 return SymbianOSError(mp4Err);
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.
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.
641 If the function returns KErr3gpLibMoreDataRequired, the caller needs to call C3GPParse::InsertData
642 to insert more data before calling the function again.
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.
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.
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.
664 EXPORT_C TInt C3GPParse::ReadVideoFrame(TDes8& aBuffer, TBool& aKeyFrame, TUint& aTimeStampInMs,
665 TUint& aTimeStampInTimescale) const
671 if (aBuffer.MaxLength() <= 0)
676 // Check if 3GP input data contains video stream
677 TInt err = DoGetVideoProperties();
683 mp4_u32 frameSize = 0;
684 mp4_u32 timeStamp = 0;
685 mp4_bool keyFrame = EFalse;
686 mp4_u32 timestamp2 = 0;
688 MP4Err mp4Err = MP4ParseReadVideoFrame(iHandler, const_cast<mp4_u8*>(aBuffer.Ptr()), aBuffer.MaxLength(),
689 &frameSize, &timeStamp, &keyFrame, ×tamp2);
691 if (mp4Err == MP4_OK)
693 aBuffer.SetLength(frameSize);
694 aKeyFrame = keyFrame;
695 aTimeStampInMs = timeStamp;
696 aTimeStampInTimescale = timestamp2;
698 return SymbianOSError(mp4Err);
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.
706 Note: Only MPEG-4 video and H.264/AVC video streams contain DecoderSpecificInfo.
708 @param aSize Size of video DecoderSpecificInfo.
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.
718 EXPORT_C TInt C3GPParse::GetVideoDecoderSpecificInfoSize(TInt& aSize) const
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();
731 iVideoType == E3GPMpeg4Video ||
732 iVideoType == E3GPAvcProfileBaseline ||
733 iVideoType == E3GPAvcProfileMain ||
734 iVideoType == E3GPAvcProfileExtended ||
735 iVideoType == E3GPAvcProfileHigh
738 return KErrNotSupported;
746 mp4_u32 decspecinfosize = 0;
747 MP4Err mp4Err = MP4ParseReadVideoDecoderSpecificInfo(iHandler, NULL, 0, &decspecinfosize);
749 if ( mp4Err == MP4_OK || mp4Err == MP4_BUFFER_TOO_SMALL)
751 aSize = decspecinfosize;
755 return SymbianOSError(mp4Err);
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.
763 Note: Only MPEG-4 video and H.264/AVC video streams contain DecoderSpecificInfo.
765 @see C3GPParse::GetVideoDecoderSpecificInfoSize
767 @param aInfo The descriptor to store the video decoder information.
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.
778 EXPORT_C TInt C3GPParse::GetVideoDecoderSpecificInfo(TDes8& aInfo) const
784 if (aInfo.MaxLength() <= 0)
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();
795 iVideoType == E3GPMpeg4Video ||
796 iVideoType == E3GPAvcProfileBaseline ||
797 iVideoType == E3GPAvcProfileMain ||
798 iVideoType == E3GPAvcProfileExtended ||
799 iVideoType == E3GPAvcProfileHigh
802 return KErrNotSupported;
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)
815 aInfo.SetLength(decspecinfosize);
817 return SymbianOSError(mp4Err);
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.
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.
827 If the function returns KErr3gpLibMoreDataRequired, the caller needs to call C3GPParse::InsertData
828 to insert more data before calling the function again.
830 Note: aReturnedFrames may differ from the correct value when accessing the last audio sample.
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.
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
839 @param aTimeStampInTimescale Audio frame presentation time in timescale from the beginning
840 of the audio sequence.
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.
854 EXPORT_C TInt C3GPParse::ReadAudioFrames(TDes8& aBuffer, TInt& aReturnedFrames, TUint& aTimeStampInMs,
855 TUint& aTimeStampInTimescale) const
861 if (aBuffer.MaxLength() <= 0)
866 // Check if 3GP input data contains audio stream
867 TInt err = DoGetAudioProperties();
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)
881 aBuffer.SetLength(audioSize);
882 aReturnedFrames = numOfFrames;
883 aTimeStampInMs = timeStampInMs;
884 aTimeStampInTimescale = timeStampInTimescale;
886 return SymbianOSError(mp4Err);
890 Returns size of audio DecoderSpecificInfo data from 3GP metadata.
892 @param aSize Size of DecoderSpecificInfo to be returned (in bytes).
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.
902 EXPORT_C TInt C3GPParse::GetAudioDecoderSpecificInfoSize(TInt& aSize) const
909 // Check if 3GP input data contains audio stream
910 TInt err = DoGetAudioProperties();
916 mp4_u32 decspecinfosize = 0;
917 MP4Err mp4Err = MP4ParseReadAudioDecoderSpecificInfo(iHandler, NULL, 0, &decspecinfosize);
918 if ( mp4Err == MP4_OK || mp4Err == MP4_BUFFER_TOO_SMALL)
920 aSize = decspecinfosize;
923 return SymbianOSError(mp4Err);
927 This function reads DecoderSpecificInfo data from 3GP metadata and returns it to the caller.
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.
932 @see C3GPParse::GetAudioDecoderSpecificInfoSize
934 @param aBuffer DecoderSpecificInfo is returned here.
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.
945 EXPORT_C TInt C3GPParse::GetAudioDecoderSpecificInfo(TDes8& aBuffer) const
951 if (aBuffer.MaxLength() <= 0)
956 // Check if 3GP input data contains audio stream
957 TInt err = DoGetAudioProperties();
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)
968 aBuffer.SetLength(decspecinfosize);
970 return SymbianOSError(mp4Err);
974 Returns the timestamp of the next video frame. The current position of the video stream will be moved forward.
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.
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.
982 Note: C3GPParse::Seek can be used to change the current position in the 3GP file.
984 @param aTimeStampInMs Timestamp in milliseconds is returned here.
985 @param aTimeStampInTimescale Timestamp in timescale is returned here.
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.
996 EXPORT_C TInt C3GPParse::GetVideoTimestamp(TUint& aTimeStampInMs, TUint& aTimeStampInTimescale) const
1000 return KErrNotReady;
1003 // Check if 3GP input data contains video stream
1004 TInt err = DoGetVideoProperties();
1005 if (err != KErrNone)
1010 mp4_u32 timeStampInMs = 0;
1011 mp4_u32 timeStampInTimescale = 0;
1012 MP4Err mp4Err = MP4ParseGetNextVideoTimestamp(iHandler, &timeStampInMs, &timeStampInTimescale);
1013 if (mp4Err == MP4_OK)
1015 aTimeStampInMs = timeStampInMs;
1016 aTimeStampInTimescale = timeStampInTimescale;
1018 return SymbianOSError(mp4Err);
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.
1025 @param aStreamable Returns ETrue if the file is streamable. Otherwise, returns EFalse.
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.
1034 EXPORT_C TInt C3GPParse::GetStreamable(TBool& aStreamable) const
1038 return KErrNotReady;
1041 MP4Err mp4Err = MP4ParseIsStreamable(iHandler);
1042 if (mp4Err == MP4_OK)
1044 aStreamable = ETrue;
1048 aStreamable = EFalse;
1050 return SymbianOSError(mp4Err);
1054 This function seeks the position specified by the aPosition parameter in the input 3GP file/stream.
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.
1059 The function will set the current audio and video positions in the following manner:
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.
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.
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.
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.
1074 If the function returns KErr3gpLibMoreDataRequired, the caller needs to call C3GPParse::InsertData
1075 to insert more data before calling the function again.
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).
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;
1090 EXPORT_C TInt C3GPParse::Seek(TUint aPosition, TBool aKeyFrame, TUint& aAudioPosition, TUint& aVideoPosition) const
1094 return KErrNotReady;
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)
1103 aAudioPosition = audioPosition;
1104 aVideoPosition = videoPosition;
1106 return SymbianOSError(mp4Err);
1110 This function determines whether the next frame of the type aType is available.
1112 This function has no effect on the parser’s current position.
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.
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.
1125 EXPORT_C TInt C3GPParse::GetFrameAvailability(T3GPFrameType aType, TBool& aAvailable) const
1129 return KErrNotReady;
1132 aAvailable = EFalse;
1133 TInt err = KErrNone;
1134 MP4Err mp4Err = MP4_OK;
1135 if (aType == E3GPAudio)
1137 // Check if 3GP input data contains audio stream
1138 err = DoGetAudioProperties();
1139 if (err == KErrNotSupported)
1141 // If there is no requested type, err will be KErrNotSupported. But in here, KErrNotFound is
1145 else if (err == KErrNone)
1147 mp4Err = MP4ParseIsFrameAvailable(iHandler, iAudioMp4Type);
1148 err = SymbianOSError(mp4Err);
1151 else if (aType == E3GPVideo)
1153 // Check if 3GP input data contains video stream
1154 err = DoGetVideoProperties();
1155 if (err == KErrNotSupported)
1157 // If there is no requested type, err will be KErrNotSupported. But in here, KErrNotFound is
1161 else if (err == KErrNone)
1163 mp4Err = MP4ParseIsFrameAvailable(iHandler, iVideoMp4Type);
1164 err = SymbianOSError(mp4Err);
1169 Panic(KErrArgument); // This should not happen.
1172 if (err == KErrNone)
1180 Returns the number of video frames.
1182 @param aNum Number of video frames.
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.
1189 EXPORT_C TInt C3GPParse::GetNumberOfVideoFrames(TUint& aNum) const
1193 return KErrNotReady;
1196 // Check if 3GP input data contains video stream
1197 TInt err = DoGetVideoProperties();
1198 if (err != KErrNone)
1203 mp4_u32 numVideoFrame = 0;
1204 MP4Err mp4Err = MP4ParseGetNumberOfVideoFrames(iHandler, &numVideoFrame);
1205 if (mp4Err == MP4_OK)
1207 aNum = numVideoFrame;
1209 return SymbianOSError(mp4Err);
1213 This function gives the video sample entry index of the next video frame to be read.
1215 The smallest index value is 1.
1217 @param aIndex Returns the Visual Sample Entry index of the next video frame to be read.
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.
1224 EXPORT_C TInt C3GPParse::GetVideoSampleEntryIndex(TUint& aIndex) const
1228 return KErrNotReady;
1231 // Check if 3GP input data contains video stream
1232 TInt err = DoGetVideoProperties();
1233 if (err != KErrNone)
1239 MP4Err mp4Err = MP4ParseGetVideoSampleEntryIndex(iHandler, &index);
1240 if (mp4Err == MP4_OK)
1244 return SymbianOSError(mp4Err);
1248 Returns video frame size.
1250 @param aIndex Index of video frame.
1251 @param aSize Return the size of the video frame.
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.
1258 EXPORT_C TInt C3GPParse::GetVideoFrameSize(TUint aIndex, TUint& aSize) const
1262 return KErrNotReady;
1265 // Check if 3GP input data contains video stream
1266 TInt err = DoGetVideoProperties();
1267 if (err != KErrNone)
1272 mp4_u32 videoFrameSize = 0;
1273 MP4Err mp4Err = MP4ParseGetVideoFrameSize(iHandler, aIndex, &videoFrameSize);
1274 if (mp4Err == MP4_OK)
1276 aSize = videoFrameSize;
1278 return SymbianOSError(mp4Err);
1282 Returns video frame start time.
1284 @param aIndex Index of video frame.
1285 @param aTimeStampInMs Result in milliseconds.
1286 @param aTimeStampInTimescale Result is returned here.
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.
1293 EXPORT_C TInt C3GPParse::GetVideoFrameStartTime(TUint aIndex, TUint& aTimeStampInMs, TUint& aTimeStampInTimescale) const
1297 return KErrNotReady;
1300 // Check if 3GP input data contains video stream
1301 TInt err = DoGetVideoProperties();
1302 if (err != KErrNone)
1307 mp4_u32 timeStampInMs = 0;
1308 mp4_u32 timeStampInTimescale = 0;
1309 MP4Err mp4Err = MP4ParseGetVideoFrameStartTime(iHandler, aIndex, &timeStampInTimescale, &timeStampInMs);
1310 if (mp4Err == MP4_OK)
1312 aTimeStampInMs = timeStampInMs;
1313 aTimeStampInTimescale = timeStampInTimescale;
1315 return SymbianOSError(mp4Err);
1319 Checks if a video frame of with index aIndex exists.
1321 @param aIndex Index of video frame.
1322 @param aKeyFrame Return ETrue if the video frame is a key frame.
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.
1329 EXPORT_C TInt C3GPParse::GetVideoFrameKeyType(TUint aIndex, TBool& aKeyFrame) const
1333 return KErrNotReady;
1336 // Check if 3GP input data contains video stream
1337 TInt err = DoGetVideoProperties();
1338 if (err != KErrNone)
1343 mp4_bool keyFrame = EFalse;
1344 MP4Err mp4Err = MP4ParseGetVideoFrameType(iHandler, aIndex, &keyFrame);
1345 if (mp4Err == MP4_OK)
1347 aKeyFrame = keyFrame;
1349 return SymbianOSError(mp4Err);
1353 This function gives the audio sample entry index of the next audio frame to be read.
1355 The smallest index value is 1.
1357 @param aIndex Returns the Audio Sample Entry index of the next video frame to be read.
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.
1364 EXPORT_C TInt C3GPParse::GetAudioSampleEntryIndex(TUint& aIndex) const
1368 return KErrNotReady;
1371 // Check if 3GP input data contains audio stream
1372 TInt err = DoGetAudioProperties();
1373 if (err != KErrNone)
1378 mp4_u32 audioSampleEntryIndex = 0;
1379 MP4Err mp4Err = MP4ParseGetAudioSampleEntryIndex(iHandler, &audioSampleEntryIndex);
1380 if (mp4Err == MP4_OK)
1382 aIndex = audioSampleEntryIndex;
1384 return SymbianOSError(mp4Err);
1388 This function provides the storage mode of 13K QCELP in 3G2 file.
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.
1394 @param aMode Returns the QCELP storage mode. See T3GPQcelpStorageMode.
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.
1401 EXPORT_C TInt C3GPParse::GetQcelpStorageMode(T3GPQcelpStorageMode& aMode) const
1405 return KErrNotReady;
1408 // Check if 3GP input data contains any QCELP audio stream
1409 TInt err = DoGetAudioProperties();
1410 if (err == KErrNone)
1412 if (iAudioType != E3GPQcelp13K)
1414 return KErrNotSupported;
1422 mp4_u8 audioQcelpStorageMode = 0;
1423 MP4Err mp4Err = MP4ParseGetQCELPStorageMode(iHandler, &audioQcelpStorageMode);
1424 if (mp4Err == MP4_OK)
1426 if (audioQcelpStorageMode == 1)
1428 aMode = E3GPMP4AudioDescriptionBox;
1432 aMode = E3GPQcelpSampleEntryBox;
1435 return SymbianOSError(mp4Err);
1439 This function provides the video level of the H263 video stream contained in the 3GP data.
1441 @param aLevel Returns the H263 video level.
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.
1448 EXPORT_C TInt C3GPParse::GetH263VideoLevel(TInt& aLevel) const
1452 return KErrNotReady;
1455 // Check if 3GP input data contains any H263 video stream
1456 TInt err = DoGetVideoProperties();
1457 if (err == KErrNone)
1459 if (!(iVideoType == E3GPH263Profile0 || iVideoType == E3GPH263Profile3))
1461 return KErrNotSupported;
1469 TVideoClipProperties videoClipProperties;
1470 MP4Err mp4Err = MP4ParseGetVideoClipProperties(iHandler, videoClipProperties);
1471 if (mp4Err == MP4_OK)
1473 aLevel = videoClipProperties.iH263Level;
1475 return SymbianOSError(mp4Err);
1479 Returns the needed size for memory buffer to store an atom of given type from user data atom (UDTA).
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
1489 @param aSize This contains the needed size for memory buffer.
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.
1498 @panic C3GPParse KErrArgument if the location of user information is not in the range of T3GPUdtaLocation
1500 EXPORT_C TInt C3GPParse::GetUserDataAtomSize(TUint32 aType, T3GPUdtaLocation aLocation,
1501 TUint& aAtomIndex, TInt& aSize) const
1505 return KErrNotReady;
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)
1516 aSize = userDataAtomSize;
1517 aAtomIndex = atomIndex;
1520 return SymbianOSError(mp4Err);
1524 Retrieves an atom of given type from user data atom (UDTA) to the given buffer.
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."
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)."
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
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.
1555 @panic C3GPParse KErrArgument if the location of user information is not in the range of T3GPUdtaLocation
1557 EXPORT_C TInt C3GPParse::GetUserDataAtom(TUint32 aType, T3GPUdtaLocation aLocation, TDes8& aBuffer, TUint& aAtomIndex) const
1561 return KErrNotReady;
1563 if (aBuffer.MaxLength() <= 0)
1565 return KErrOverflow;
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 )
1577 aBuffer.SetLength(userDataAtomSize);
1578 aAtomIndex = atomIndex;
1580 return SymbianOSError(mp4Err);
1584 This function gets the next frame's dependency information from SDTP box.
1586 @param aDependencies Returns the next frame's dependency information. See T3GPFrameDependencies.
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.
1595 EXPORT_C TInt C3GPParse::GetVideoFrameDependencies(T3GPFrameDependencies& aDependencies) const
1599 return KErrNotReady;
1602 // Check if 3GP input data contains video stream
1603 TInt err = DoGetVideoProperties();
1604 if (err != KErrNone)
1610 mp4_u8 isDependedOn;
1611 mp4_u8 hasRedundancy;
1612 MP4Err mp4Err = MP4ParseNextVideoFrameDependencies(iHandler, &dependsOn, &isDependedOn, &hasRedundancy);
1613 if (mp4Err == MP4_OK)
1618 aDependencies.iDependsOn = E3GPDependencyExists;
1621 aDependencies.iDependsOn = E3GPDependencyNone;
1624 aDependencies.iDependsOn = E3GPDependencyUnknown;
1630 switch (isDependedOn)
1633 aDependencies.iIsDependedOn = E3GPDependencyExists;
1636 aDependencies.iIsDependedOn = E3GPDependencyNone;
1639 aDependencies.iIsDependedOn = E3GPDependencyUnknown;
1645 switch (hasRedundancy)
1648 aDependencies.iHasRedundancy = E3GPRedundancyExists;
1651 aDependencies.iHasRedundancy = E3GPRedundancyNone;
1654 aDependencies.iHasRedundancy = E3GPRedundancyUnknown;
1660 return SymbianOSError(mp4Err);
1664 This function gets frame properties, from aStartIndex for a count of aNumberOfFrames frames.
1666 Properties obtained are start time, frame type, and frame size, stored in the T3GPFrameInfoParameters
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.
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.
1681 EXPORT_C TInt C3GPParse:: GetVideoFrameProperties(TUint aStartIndex, TUint aNumberOfFrames,
1682 RArray<T3GPFrameInfoParameters>& aArray) const
1686 return KErrNotReady;
1689 // Check if 3GP input data contains video stream
1690 TInt err = DoGetVideoProperties();
1691 if (err != KErrNone)
1696 // Check if the input parameters are valid before retrieving video frame properties.
1697 TUint totalNumOfVideoFrames;
1698 err = GetNumberOfVideoFrames(totalNumOfVideoFrames);
1699 if (err != KErrNone)
1704 if (aStartIndex >= totalNumOfVideoFrames || aNumberOfFrames > totalNumOfVideoFrames)
1709 TFrameInfoParameters* infoArray = new TFrameInfoParameters[aNumberOfFrames];
1713 return KErrNoMemory;
1716 mp4_u32 startIndex = aStartIndex;
1717 mp4_u32 numberOfFrames = aNumberOfFrames;
1718 MP4Err mp4Err = MP4GetVideoFrameProperties(iHandler, startIndex, numberOfFrames, infoArray);
1720 if ( mp4Err == MP4_OK )
1723 T3GPFrameInfoParameters infoParams;
1725 for (TInt i=0; i<aNumberOfFrames; ++i)
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)
1733 delete [] infoArray;
1741 err = SymbianOSError(mp4Err);
1743 delete [] infoArray;
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.
1752 This function is not supported when the parser is in buffer mode.
1754 C3GPParse::CancelReadFrame can be used to cancel an outstanding asynchronous frame read request.
1756 Note: Only one asynchronous parse audio or video frame(s) operation can be ongoing at any given time.
1758 Upon completion, successfully or otherwise, the callback function M3GPParseCallback::VideoFrameAvailable is called.
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.
1764 EXPORT_C void C3GPParse::ReadVideoFrame(M3GPParseCallback& aCallback, TDes8& aBuffer)
1768 aCallback.VideoFrameAvailable(KErrNotReady, EFalse, 0, 0);
1771 if (aBuffer.MaxLength() <= 0)
1773 aCallback.VideoFrameAvailable(KErrOverflow, EFalse, 0, 0);
1776 if (iAsyncReadBuffer)
1778 aCallback.VideoFrameAvailable(KErrInUse, EFalse, 0, 0);
1782 // Check if 3GP input data contains video stream
1783 TInt err = DoGetVideoProperties();
1784 if (err != KErrNone)
1786 aCallback.VideoFrameAvailable(err, EFalse, 0, 0);
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)
1796 aCallback.VideoFrameAvailable(SymbianOSError(mp4Err), EFalse, 0, 0);
1800 // MP4ParseReadVideoFrameAsync success. Store aBuffer since its length has
1802 iAsyncReadBuffer = &aBuffer;
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.
1811 This function is not supported when the parser is in buffer mode.
1813 C3GPParse::CancelReadFrame can be used to cancel an outstanding asynchronous frame read request.
1815 Note: Only one asynchronous parse audio or video frame(s) operation can be ongoing at any given time.
1817 Upon completion, successfully or otherwise, the callback function M3GPParseCallback::AudioFramesAvailable is called.
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.
1823 EXPORT_C void C3GPParse::ReadAudioFrames(M3GPParseCallback& aCallback, TDes8& aBuffer)
1827 aCallback.AudioFramesAvailable(KErrNotReady, 0, 0, 0);
1830 if (aBuffer.MaxLength() <= 0)
1832 aCallback.AudioFramesAvailable(KErrOverflow, 0, 0, 0);
1835 if (iAsyncReadBuffer)
1837 aCallback.AudioFramesAvailable(KErrInUse, 0, 0, 0);
1841 // Check if 3GP input data contains audio stream
1842 TInt err = DoGetAudioProperties();
1843 if (err != KErrNone)
1845 aCallback.AudioFramesAvailable(err, 0, 0, 0);
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)
1855 aCallback.AudioFramesAvailable(SymbianOSError(mp4Err), 0, 0, 0);
1859 // MP4ParseReadAudioFramesAsync success. Store aBuffer since its length has
1861 iAsyncReadBuffer = &aBuffer;
1866 This function cancels the outstanding asynchronous read audio/video frame request.
1868 No callback function will be called.
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.
1873 EXPORT_C void C3GPParse::CancelReadFrame()
1879 if (iAsyncReadBuffer)
1881 MP4CancelReadFrame(iHandler);
1882 iAsyncReadBuffer = NULL;
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)
1891 // Check if there is an outstanding asynchronous request
1892 if (iAsyncReadBuffer)
1894 if (aError == MP4_OK)
1896 // Set the buffer length for the asynchronous read video frame
1897 iAsyncReadBuffer->SetLength(aFrameSize);
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);
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)
1914 // Check if there is an outstanding asynchronous request
1915 if (iAsyncReadBuffer)
1917 if (aError == MP4_OK)
1919 // Set the buffer length for the asynchronous read audio frame
1920 iAsyncReadBuffer->SetLength(aAudioSize);
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);
1933 // Helper function to convert c style error code to Symbian OS standard error code
1934 TInt C3GPParse::SymbianOSError(MP4Err aError) const
1936 TInt error = KErrNone;
1943 error = KErrGeneral;
1945 case (MP4_OUT_OF_MEMORY):
1946 error = KErrNoMemory;
1948 case (MP4_NOT_AVAILABLE):
1949 error = KErr3gpLibMoreDataRequired;
1951 case (MP4_FILE_MODE):
1952 case (MP4_NOT_STREAMABLE):
1953 case (MP4_NO_VIDEO):
1954 case (MP4_NO_AUDIO):
1955 error = KErrNotSupported;
1957 case (MP4_BUFFER_TOO_SMALL):
1958 case (MP4_OUTPUT_BUFFER_TOO_SMALL):
1959 error = KErrOverflow;
1961 case (MP4_END_OF_VIDEO):
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;
1970 case (MP4_FILE_ERROR):
1971 error = KErrAccessDenied;
1973 case (MP4_INVALID_INPUT_STREAM):
1974 error = KErrCorrupt;
1976 case (MP4_INVALID_TYPE):
1977 error = KErrArgument;
1980 // Mapped all possible errors returned by the MP4_library. Anything else should NOT happen
1981 Panic(KErrArgument);
1986 // Help function to get video properties
1987 TInt C3GPParse::DoGetVideoProperties() const
1989 if (!iVideoPropertiesSaved || iVideoError == KErr3gpLibMoreDataRequired)
1991 MP4Err mp4Err = MP4_OK;
1996 mp4_u32 timeScale = 0;
1997 mp4_double frameRate = 0;
1999 mp4Err = MP4ParseRequestVideoDescription(iHandler, &length, &frameRate, &type, &width, &height, &timeScale);
2000 iVideoPropertiesSaved = ETrue;
2001 if (mp4Err == MP4_OK)
2003 iVideoType = WrapperVideoType(type);
2004 if (iVideoType == E3GPNoVideo)
2006 iVideoError = KErrNotSupported;
2007 return KErrNotSupported;
2009 iVideoLength = length;
2010 iVideoMp4Type = type; // Type of video stream
2011 iVideoSize.iWidth = width;
2012 iVideoSize.iHeight = height;
2013 iVideoTimeScale = timeScale;
2014 iVideoFrameRate = frameRate;
2016 iVideoError = SymbianOSError(mp4Err);
2021 // Help function to get audio properties
2022 TInt C3GPParse::DoGetAudioProperties() const
2024 if (!iAudioPropertiesSaved || iAudioError == KErr3gpLibMoreDataRequired)
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;
2033 mp4Err = MP4ParseRequestAudioDescription(iHandler, &audioLength, &audioType,
2034 &framesPerSample, &timeScale, &averateBitRate);
2035 iAudioPropertiesSaved = ETrue;
2036 if (mp4Err == MP4_OK)
2038 iAudioLength = audioLength;
2039 iAudioMp4Type = audioType; // Type of audio stream
2040 iAudioType = WrapperAudioType(audioType);
2041 iAudioFramesPerSample = framesPerSample;
2042 iAudioAvgBitRate = averateBitRate;
2043 iAudioTimeScale = timeScale;
2045 iAudioError = SymbianOSError(mp4Err);
2050 // Help function to get stream properties
2051 TInt C3GPParse::DoGetStreamProperties() const
2053 if (!iStreamPropertiesSaved || iStreamError == KErr3gpLibMoreDataRequired)
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)
2062 iStreamSize = streamSize;
2063 iStreamAvgBitRate = streamAvgBitRate;
2065 iStreamError = SymbianOSError(mp4Err);
2067 return iStreamError;
2070 // Helper function to map Mp4 enum type to T3GPVideoType for video
2071 T3GPVideoType C3GPParse::WrapperVideoType(TUint aType) const
2073 T3GPVideoType videoType = E3GPNoVideo;
2076 case (MP4_TYPE_MPEG4_VIDEO):
2077 videoType = E3GPMpeg4Video;
2079 case (MP4_TYPE_H263_PROFILE_0):
2080 videoType = E3GPH263Profile0;
2082 case (MP4_TYPE_H263_PROFILE_3):
2083 videoType = E3GPH263Profile3;
2085 case (MP4_TYPE_AVC_PROFILE_BASELINE):
2086 videoType = E3GPAvcProfileBaseline;
2088 case (MP4_TYPE_AVC_PROFILE_MAIN):
2089 videoType = E3GPAvcProfileMain;
2091 case (MP4_TYPE_AVC_PROFILE_EXTENDED):
2092 videoType = E3GPAvcProfileExtended;
2095 case (MP4_TYPE_AVC_PROFILE_HIGH):
2096 videoType = E3GPAvcProfileHigh;
2101 Panic(KErrCorrupt); // This should not happen.
2107 // Helper function to map Mp4 enum type to T3GPAudioType for audio
2108 T3GPAudioType C3GPParse::WrapperAudioType(TUint aType) const
2110 T3GPAudioType audioType = E3GPNoAudio;
2113 case (MP4_TYPE_MPEG4_AUDIO):
2114 audioType = E3GPMpeg4Audio;
2116 case (MP4_TYPE_AMR_NB):
2117 audioType = E3GPAmrNB;
2119 case (MP4_TYPE_AMR_WB):
2120 audioType = E3GPAmrWB;
2122 case (MP4_TYPE_QCELP_13K):
2123 audioType = E3GPQcelp13K;
2126 Panic(KErrCorrupt); // This should not happen.
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
2134 mp4_u8 location = MP4_UDTA_NONE;
2138 case (E3GPUdtaMoov):
2139 location = MP4_UDTA_MOOV;
2141 case (E3GPUdtaVideoTrak):
2142 location = MP4_UDTA_VIDEOTRAK;
2144 case (E3GPUdtaAudioTrak):
2145 location = MP4_UDTA_AUDIOTRAK;
2148 Panic(KErrArgument);
2154 void C3GPParse::Panic(TInt aPanic)
2157 _LIT(K3GPParsePanicName, "C3GPParse");
2158 User::Panic(K3GPParsePanicName, aPanic);