First public contribution.
1 // Copyright (c) 2006-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 <3gplibrary/mp4config.h>
17 #include <3gplibrary/mp4lib.h>
19 #include "mp4memwrap.h"
21 #include "mp4buffer.h"
22 #include "mp4endian.h"
25 using namespace ContentAccess;
27 extern EXPORT_C MP4Err MP4ParseOpen(MP4Handle *apihandle,
30 MP4HandleImp *handle = (MP4HandleStruct **)apihandle;
31 *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
33 return MP4_OUT_OF_MEMORY;
35 (*handle)->file32Duplicate = NULL;
36 (*handle)->FileHandleFromOutside = EFalse;
37 (*handle)->sourceType = MP4_SOURCE_RFILE;
40 if (initFileRead(filename, *handle) == -1)
45 return MP4_FILE_ERROR;
48 (*handle)->mem = listCreate();
49 if ((*handle)->mem == NULL)
54 return MP4_OUT_OF_MEMORY;
57 if (((*handle)->buf = (mp4_u8 *)mp4malloc(TMPBUFSIZE)) == NULL)
59 listDestroyList((*handle)->mem);
63 return MP4_OUT_OF_MEMORY;
66 if (((*handle)->diskReadBuf = (mp4_u8 *)mp4malloc(READBUFSIZE)) == NULL)
68 mp4free((*handle)->buf);
69 listDestroyList((*handle)->mem);
73 return MP4_OUT_OF_MEMORY;
76 // register for stblib use
77 if (openStdlib() != MP4_OK)
79 mp4free((*handle)->diskReadBuf);
80 mp4free((*handle)->buf);
81 listDestroyList((*handle)->mem);
92 extern EXPORT_C MP4Err MP4ParseOpenFileHandle(MP4Handle *apihandle,
96 RFile64 *f64 = new RFile64;
99 return MP4_OUT_OF_MEMORY;
101 if (f64->Duplicate(*inputfile) != KErrNone)
106 err = MP4ParseOpenFileHandle64(apihandle, f64);
109 MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
110 (*handle)->file32Duplicate = (void*)(f64);
115 extern EXPORT_C MP4Err MP4ParseOpenFileHandle64(MP4Handle *apihandle,
118 MP4HandleImp *handle = (MP4HandleStruct **)apihandle;
119 *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
121 return MP4_OUT_OF_MEMORY;
123 (*handle)->file32Duplicate = NULL;
124 (*handle)->rfile = (void *)inputfile;
125 (*handle)->file = (*handle)->rfile;
126 (*handle)->FileHandleFromOutside = ETrue;
127 (*handle)->sourceType = MP4_SOURCE_RFILE;
128 if (inputfile == NULL)
133 return MP4_FILE_ERROR;
136 (*handle)->mem = listCreate();
137 if ((*handle)->mem == NULL)
142 return MP4_OUT_OF_MEMORY;
145 if (((*handle)->buf = (mp4_u8 *)mp4malloc(TMPBUFSIZE)) == NULL)
147 listDestroyList((*handle)->mem);
151 return MP4_OUT_OF_MEMORY;
154 if (((*handle)->diskReadBuf = (mp4_u8 *)mp4malloc(READBUFSIZE)) == NULL)
156 mp4free((*handle)->buf);
157 listDestroyList((*handle)->mem);
161 return MP4_OUT_OF_MEMORY;
164 // register for stblib use
165 if (openStdlib() != MP4_OK)
168 mp4free((*handle)->diskReadBuf);
169 mp4free((*handle)->buf);
170 listDestroyList((*handle)->mem);
181 extern EXPORT_C MP4Err MP4ParseOpenCAF(MP4Handle *apihandle,
182 ContentAccess::CData *inputfile)
184 MP4HandleImp *handle = (MP4HandleStruct **)apihandle;
185 *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
187 return MP4_OUT_OF_MEMORY;
189 (*handle)->file32Duplicate = NULL;
190 (*handle)->cfile = inputfile;
191 (*handle)->file = (*handle)->cfile;
192 (*handle)->FileHandleFromOutside = ETrue;
193 (*handle)->sourceType = MP4_SOURCE_CAF;
195 if (inputfile == NULL)
200 return MP4_FILE_ERROR;
203 (*handle)->mem = listCreate();
204 if ((*handle)->mem == NULL)
209 return MP4_OUT_OF_MEMORY;
212 if (((*handle)->buf = (mp4_u8 *)mp4malloc(TMPBUFSIZE)) == NULL)
214 listDestroyList((*handle)->mem);
218 return MP4_OUT_OF_MEMORY;
221 if (((*handle)->diskReadBuf = (mp4_u8 *)mp4malloc(READBUFSIZE)) == NULL)
223 mp4free((*handle)->buf);
224 listDestroyList((*handle)->mem);
228 return MP4_OUT_OF_MEMORY;
231 // register for stblib use
232 if (openStdlib() != MP4_OK)
235 mp4free((*handle)->diskReadBuf);
236 mp4free((*handle)->buf);
237 listDestroyList((*handle)->mem);
248 extern EXPORT_C MP4Err MP4ParseClose(MP4Handle apihandle)
250 MP4HandleImp handle = (MP4HandleImp)apihandle;
258 closeStdlib(); /* Free memory allocated by stdlib wrapper functions */
260 listDestroyList(handle->mem);
262 if (handle->diskReadBuf)
263 mp4free(handle->diskReadBuf);
266 mp4free(handle->buf);
268 if (freeMOOV(handle->moov) < 0)
271 if (freeFTYP(handle->ftyp) < 0)
274 if (handle->file32Duplicate)
275 ((RFile64*)handle->file32Duplicate)->Close();
283 extern EXPORT_C MP4Err MP4ParseRequestVideoDescription(MP4Handle apihandle,
284 mp4_u32 *videolength,
285 mp4_double *framerate,
288 mp4_u32 *videoheight,
291 MP4HandleImp handle = (MP4HandleImp)apihandle;
297 if (!handle->metaDataComplete)
299 switch (metaDataAvailable(handle))
302 return MP4_NOT_AVAILABLE;
305 handle->cafError = KErrNone;
306 if (readMetaData(handle) < 0)
308 // Reading of meta data failed, so free up any allocated memory
309 freeFTYP(handle->ftyp);
311 freeMOOV(handle->moov);
314 if ( handle->cafError != KErrNone )
316 // if CAF/DRM caused the error return it instead of generic errorcode.
317 return handle->cafError;
321 return MP4_INVALID_INPUT_STREAM;
324 handle->metaDataComplete = MP4TRUE;
328 // Reading of FTYP meta data failed, so free up any allocated memory
329 freeFTYP(handle->ftyp);
341 if (!handle->moov->trakVideo)
344 mp4_i32 videoError = 0;
345 videoError = determineVideoType(handle, videotype);
346 if ( videoError == -2 )
350 else if ( videoError < 0 )
355 if (determineVideoLength(handle, videolength) < 0)
358 if (determineFrameRate(handle, framerate) < 0)
361 if (determineVideoResolution(handle, videowidth, videoheight) < 0)
364 if (determineVideoTimeScale(handle, timescale) < 0)
371 extern EXPORT_C MP4Err MP4ParseRequestAudioDescription(MP4Handle apihandle,
372 mp4_u32 *audiolength,
374 mp4_u8 *framespersample,
376 mp4_u32 *averagebitrate)
378 MP4HandleImp handle = (MP4HandleImp)apihandle;
384 if (!handle->metaDataComplete)
386 switch (metaDataAvailable(handle))
389 return MP4_NOT_AVAILABLE;
392 handle->cafError = KErrNone;
393 if (readMetaData(handle) < 0)
395 // Reading of meta data failed, so free up any allocated memory
396 freeFTYP(handle->ftyp);
398 freeMOOV(handle->moov);
401 if ( handle->cafError != KErrNone )
403 // if CAF/DRM caused the error return it instead of generic errorcode.
404 return handle->cafError;
408 return MP4_INVALID_INPUT_STREAM;
412 handle->metaDataComplete = MP4TRUE;
416 // Reading of FTYP meta data failed, so free up any allocated memory
417 freeFTYP(handle->ftyp);
429 if (!handle->moov->trakAudio)
432 if (determineAudioLength(handle, audiolength) < 0)
435 mp4_i32 audioError = 0;
436 audioError = determineAudioType(handle, audiotype);
437 if ( audioError == -2 )
441 else if ( audioError < 0 )
446 if (determineAudioFramesPerSample(handle, framespersample) < 0)
449 if (determineAudioTimeScale(handle, timescale) < 0)
452 if (averagebitrate != NULL)
453 if (determineAudioAverageBitRate(handle, averagebitrate) < 0)
460 extern EXPORT_C MP4Err MP4ParseRequestStreamDescription(MP4Handle apihandle,
462 mp4_u32 *streamaveragebitrate)
464 MP4HandleImp handle = (MP4HandleImp)apihandle;
466 if (!handle->metaDataComplete)
468 switch (metaDataAvailable(handle))
472 return MP4_NOT_AVAILABLE;
475 handle->cafError = KErrNone;
476 if (readMetaData(handle) < 0)
478 // Reading of meta data failed, so free up any allocated memory
479 freeFTYP(handle->ftyp);
481 freeMOOV(handle->moov);
484 if ( handle->cafError != KErrNone )
486 // if CAF/DRM caused the error return it instead of generic errorcode.
487 return handle->cafError;
491 return MP4_INVALID_INPUT_STREAM;
494 handle->metaDataComplete = MP4TRUE;
498 // Reading of FTYP meta data failed, so free up any allocated memory
499 freeFTYP(handle->ftyp);
509 if (determineStreamSize(handle, streamsize) < 0)
512 if (determineStreamAverageBitRate(handle, streamaveragebitrate, *streamsize) < 0)
519 extern EXPORT_C MP4Err MP4ParseWriteData(MP4Handle apihandle,
521 mp4_u32 bytestowrite)
523 MP4HandleImp handle = (MP4HandleImp)apihandle;
528 if ((buffer == NULL) && (bytestowrite != 0))
531 if (handle->LastWriteDataCalled == MP4TRUE)
532 return MP4_ERROR; // WriteData() call has been made before with bytestowrite=0, can not call again.
534 if (bytestowrite != 0)
536 if (addData(handle, buffer, bytestowrite) == -1)
537 return MP4_OUT_OF_MEMORY;
540 handle->LastWriteDataCalled = MP4TRUE;
546 extern EXPORT_C MP4Err MP4ParseGetBufferedBytes(MP4Handle apihandle,
549 MP4HandleImp handle = (MP4HandleImp)apihandle;
551 *bytes = getBufferedBytes(handle);
554 return MP4_FILE_MODE;
559 extern EXPORT_C MP4Err MP4ParseNextFrameType(MP4Handle apihandle,
562 MP4HandleImp handle = (MP4HandleImp)apihandle;
564 if (!handle->metaDataComplete)
566 switch (metaDataAvailable(handle))
569 return MP4_NOT_AVAILABLE;
572 handle->cafError = KErrNone;
573 if (readMetaData(handle) < 0)
575 // Reading of meta data failed, so free up any allocated memory
576 freeFTYP(handle->ftyp);
578 freeMOOV(handle->moov);
581 if ( handle->cafError != KErrNone )
583 // if CAF/DRM caused the error return it instead of generic errorcode.
584 return handle->cafError;
588 return MP4_INVALID_INPUT_STREAM;
591 handle->metaDataComplete = MP4TRUE;
595 // Reading of FTYP meta data failed, so free up any allocated memory
596 freeFTYP(handle->ftyp);
606 /* No audio nor video */
607 if ((!handle->moov->trakAudio) && (!handle->moov->trakVideo))
610 mp4_u32 audiotype = 0;
611 mp4_i32 audioerror = 0;
612 if (handle->moov->trakAudio)
614 audioerror = determineAudioType(handle, &audiotype);
617 mp4_u32 videotype = 0;
618 mp4_i32 videoerror = 0;
619 if (handle->moov->trakVideo)
621 videoerror = determineVideoType(handle, &videotype);
624 /* Audio track only */
625 if (handle->moov->trakAudio && !handle->moov->trakVideo)
629 // if audio is of supported type, check if the last audio frame has been
631 if (handle->audioLast)
647 /* Video track only */
648 if (handle->moov->trakVideo && !handle->moov->trakAudio)
652 // if video is of supported type, check if the last video frame has been
654 if (handle->videoLast)
670 /* All audio has been read, but there is video left */
671 if (handle->audioLast && !handle->videoLast)
684 /* All video has been read, but there is audio left */
685 if (handle->videoLast && !handle->audioLast)
698 /* All data has been read */
699 if (handle->audioLast && handle->videoLast)
704 if (handle->audioSampleOffset < handle->videoFrameOffset)
706 /* Next frame is audio */
712 else if ( (audioerror == -2) && (videoerror == 0) )
724 /* Next frame is video */
730 else if ( (videoerror == -2) && (audioerror == 0) )
742 extern EXPORT_C MP4Err MP4ParseNextFrameSize(MP4Handle apihandle,
746 MP4HandleImp handle = (MP4HandleImp)apihandle;
748 if (!handle->metaDataComplete)
750 switch (metaDataAvailable(handle))
754 return MP4_NOT_AVAILABLE;
757 handle->cafError = KErrNone;
758 if (readMetaData(handle) < 0)
760 // Reading of meta data failed, so free up any allocated memory
761 freeFTYP(handle->ftyp);
763 freeMOOV(handle->moov);
766 if ( handle->cafError != KErrNone )
768 // if CAF/DRM caused the error return it instead of generic errorcode.
769 return handle->cafError;
773 return MP4_INVALID_INPUT_STREAM;
777 handle->metaDataComplete = MP4TRUE;
781 // Reading of FTYP meta data failed, so free up any allocated memory
782 freeFTYP(handle->ftyp);
792 switch (type & handle->type)
794 case MP4_TYPE_MPEG4_VIDEO:
795 case MP4_TYPE_H263_PROFILE_0:
796 case MP4_TYPE_H263_PROFILE_3:
797 case MP4_TYPE_AVC_PROFILE_BASELINE:
798 case MP4_TYPE_AVC_PROFILE_MAIN:
799 case MP4_TYPE_AVC_PROFILE_EXTENDED:
800 case MP4_TYPE_AVC_PROFILE_HIGH:
802 /* There is a next video frame */
804 if (!handle->videoLast)
805 *framesize = handle->videoFrameSize;
810 return MP4_NO_REQUESTED_FRAME;
815 case MP4_TYPE_MPEG4_AUDIO:
816 case MP4_TYPE_AMR_NB:
817 case MP4_TYPE_AMR_WB:
818 case MP4_TYPE_QCELP_13K:
820 /* There is a next audio frame */
822 if (!handle->audioLast)
823 *framesize = handle->audioSampleSize;
828 return MP4_NO_REQUESTED_FRAME;
836 if (type == MP4_TYPE_MPEG4_VIDEO ||
837 type == MP4_TYPE_H263_PROFILE_0 ||
838 type == MP4_TYPE_H263_PROFILE_3 ||
839 type == MP4_TYPE_MPEG4_AUDIO ||
840 type == MP4_TYPE_AMR_NB ||
841 type == MP4_TYPE_AMR_WB ||
843 type == MP4_TYPE_QCELP_13K
845 return MP4_NO_REQUESTED_FRAME;
847 return MP4_INVALID_TYPE;
853 extern EXPORT_C MP4Err MP4ParseReadVideoFrame(MP4Handle apihandle,
861 MP4HandleImp handle = (MP4HandleImp)apihandle;
863 if (!handle->metaDataComplete)
865 switch (metaDataAvailable(handle))
869 return MP4_NOT_AVAILABLE;
872 handle->cafError = KErrNone;
873 if (readMetaData(handle) < 0)
875 // Reading of meta data failed, so free up any allocated memory
876 freeFTYP(handle->ftyp);
878 freeMOOV(handle->moov);
881 if ( handle->cafError != KErrNone )
883 // if CAF/DRM caused the error return it instead of generic errorcode.
884 return handle->cafError;
888 return MP4_INVALID_INPUT_STREAM;
891 handle->metaDataComplete = MP4TRUE;
895 // Reading of FTYP meta data failed, so free up any allocated memory
896 freeFTYP(handle->ftyp);
906 /* Is video available? */
908 if (!((handle->type & MP4_TYPE_MPEG4_VIDEO) ||
909 (handle->type & MP4_TYPE_H263_PROFILE_0) ||
910 (handle->type & MP4_TYPE_H263_PROFILE_3) ||
911 containsAvcVideo( handle->type ) ))
914 /* Are there samples left? */
916 if (handle->videoLast)
921 if (!handle->moov->trakVideo)
924 switch (fetchVideoFrame(handle, handle->moov->trakVideo, buffer, buffersize, framesize, timestamp, keyframe, timestamp2))
929 return MP4_BUFFER_TOO_SMALL;
931 return MP4_NOT_AVAILABLE;
933 return MP4_INVALID_INPUT_STREAM;
938 switch (advanceVideoFrame(handle, handle->moov->trakVideo))
943 handle->videoLast = MP4TRUE;
952 extern EXPORT_C MP4Err MP4ParseReadVideoDecoderSpecificInfo(MP4Handle apihandle,
955 mp4_u32 *decspecinfosize)
957 MP4HandleImp handle = (MP4HandleImp)apihandle;
958 if (!handle->metaDataComplete)
960 switch (metaDataAvailable(handle))
963 return MP4_NOT_AVAILABLE;
966 handle->cafError = KErrNone;
967 if (readMetaData(handle) < 0)
969 // Reading of meta data failed, so free up any allocated memory
970 freeFTYP(handle->ftyp);
972 freeMOOV(handle->moov);
975 if ( handle->cafError != KErrNone )
977 // if CAF/DRM caused the error return it instead of generic errorcode.
978 return handle->cafError;
982 return MP4_INVALID_INPUT_STREAM;
985 handle->metaDataComplete = MP4TRUE;
989 // Reading of FTYP meta data failed, so free up any allocated memory
990 freeFTYP(handle->ftyp);
1000 /* Is video type MPEG or AVC? */
1001 if (!(handle->type & MP4_TYPE_MPEG4_VIDEO) &&
1002 !(containsAvcVideo( handle->type )) )
1011 if (!handle->moov->trakVideo)
1015 if (!handle->moov->trakVideo->mdia)
1019 if (!handle->moov->trakVideo->mdia->minf)
1023 if (!handle->moov->trakVideo->mdia->minf->stbl)
1027 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd)
1031 if (handle->videoSampleEntryIndex > handle->moov->trakVideo->mdia->minf->stbl->stsd->entryCount)
1036 TInt index = handle->videoSampleEntryIndex - 1;
1037 if (handle->videoSampleEntryIndex == 0)
1039 // even though the video sample contains no actual data, if the video sample exist
1040 // and contains decoder specific info, return it anyway
1044 if (handle->type & MP4_TYPE_MPEG4_VIDEO)
1046 /* Copy DecoderSpecificInfo into buffer */
1047 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[index])
1051 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[index]->esd)
1056 *decspecinfosize = handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[index]->esd->decSpecificInfoSize;
1057 if (buffersize < handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[index]->esd->decSpecificInfoSize)
1059 return MP4_BUFFER_TOO_SMALL;
1063 handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[index]->esd->decSpecificInfo,
1064 handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[index]->esd->decSpecificInfoSize);
1066 else if ( containsAvcVideo( handle->type ) )
1068 /* Copy the AVCDecoderConfigurationRecord into buffer */
1069 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[index])
1073 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[index]->avcc)
1078 *decspecinfosize = handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[index]->avcc->avcConfigSize;
1079 if (buffersize < handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[index]->avcc->avcConfigSize)
1081 return MP4_BUFFER_TOO_SMALL;
1085 handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[index]->avcc->avcConfig,
1086 handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[index]->avcc->avcConfigSize);
1092 extern EXPORT_C MP4Err MP4ParseReadAudioFrames(MP4Handle apihandle,
1097 mp4_u32 *returnedframes,
1098 mp4_u32 *timestamp2)
1100 MP4HandleImp handle = (MP4HandleImp)apihandle;
1102 if (!handle->metaDataComplete)
1104 switch (metaDataAvailable(handle))
1107 return MP4_NOT_AVAILABLE;
1110 handle->cafError = KErrNone;
1111 if (readMetaData(handle) < 0)
1113 // Reading of meta data failed, so free up any allocated memory
1114 freeFTYP(handle->ftyp);
1115 handle->ftyp = NULL;
1116 freeMOOV(handle->moov);
1117 handle->moov = NULL;
1119 if ( handle->cafError != KErrNone )
1121 // if CAF/DRM caused the error return it instead of generic errorcode.
1122 return handle->cafError;
1126 return MP4_INVALID_INPUT_STREAM;
1129 handle->metaDataComplete = MP4TRUE;
1133 // Reading of FTYP meta data failed, so free up any allocated memory
1134 freeFTYP(handle->ftyp);
1135 handle->ftyp = NULL;
1144 /* Is audio available? */
1146 if (!((handle->type & MP4_TYPE_MPEG4_AUDIO) ||
1147 (handle->type & MP4_TYPE_AMR_NB) ||
1148 (handle->type & MP4_TYPE_AMR_WB) ||
1149 (handle->type & MP4_TYPE_QCELP_13K)))
1152 /* Are there samples left? */
1154 if (handle->audioLast)
1155 return MP4_NO_FRAME;
1159 if (!handle->moov->trakAudio)
1162 switch (fetchAudioSample(handle, handle->moov->trakAudio, buffer, buffersize, audiosize, timestamp, returnedframes, timestamp2))
1167 return MP4_BUFFER_TOO_SMALL;
1169 return MP4_NOT_AVAILABLE;
1171 return MP4_INVALID_INPUT_STREAM;
1176 switch (advanceAudioSample(handle, handle->moov->trakAudio))
1181 handle->audioLast = MP4TRUE;
1190 extern EXPORT_C MP4Err MP4ParseReadAudioDecoderSpecificInfo(MP4Handle apihandle,
1193 mp4_u32 *decspecinfosize)
1195 MP4HandleImp handle = (MP4HandleImp)apihandle;
1197 if (!handle->metaDataComplete)
1199 switch (metaDataAvailable(handle))
1202 return MP4_NOT_AVAILABLE;
1205 handle->cafError = KErrNone;
1206 if (readMetaData(handle) < 0)
1208 // Reading of meta data failed, so free up any allocated memory
1209 freeFTYP(handle->ftyp);
1210 handle->ftyp = NULL;
1211 freeMOOV(handle->moov);
1212 handle->moov = NULL;
1214 if ( handle->cafError != KErrNone )
1216 // if CAF/DRM caused the error return it instead of generic errorcode.
1217 return handle->cafError;
1221 return MP4_INVALID_INPUT_STREAM;
1224 handle->metaDataComplete = MP4TRUE;
1228 // Reading of FTYP meta data failed, so free up any allocated memory
1229 freeFTYP(handle->ftyp);
1230 handle->ftyp = NULL;
1243 if (!handle->moov->trakAudio)
1247 if (!handle->moov->trakAudio->mdia)
1251 if (!handle->moov->trakAudio->mdia->minf)
1255 if (!handle->moov->trakAudio->mdia->minf->stbl)
1259 if (!handle->moov->trakAudio->mdia->minf->stbl->stsd)
1265 TInt index = handle->audioSampleEntryIndex - 1;
1266 if (handle->audioSampleEntryIndex == 0)
1268 // even though the audio sample contains no actual data, if the audio sample exist
1269 // and contains decoder specific info, return it anyway
1274 if ((handle->type & MP4_TYPE_MPEG4_AUDIO) ||
1275 ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio)))
1277 /* Copy DecoderSpecificInfo into buffer */
1278 if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[index])
1282 if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[index]->esd)
1287 *decspecinfosize = handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[index]->esd->decSpecificInfoSize;
1288 if (buffersize < handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[index]->esd->decSpecificInfoSize)
1290 return MP4_BUFFER_TOO_SMALL;
1294 handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[index]->esd->decSpecificInfo,
1295 handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[index]->esd->decSpecificInfoSize);
1297 else if ((handle->type & MP4_TYPE_AMR_NB) ||
1298 (handle->type & MP4_TYPE_AMR_WB) ||
1299 ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio)))
1301 /* Copy DecoderSpecificInfo into buffer */
1302 if (handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index] == NULL &&
1303 handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index] == NULL &&
1304 handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[index] == NULL)
1309 if (handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index])
1311 if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index]->damr)
1316 *decspecinfosize = 9;
1317 if (buffersize < *decspecinfosize)
1319 return MP4_BUFFER_TOO_SMALL;
1322 mp4memcpy(buffer, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index]->damr->vendor), 4);
1323 mp4memcpy(buffer+4, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index]->damr->decoderVersion), 1);
1324 mp4memcpy(buffer+5, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index]->damr->modeSet), 2);
1325 mp4memcpy(buffer+7, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index]->damr->modeChangePeriod), 1);
1326 mp4memcpy(buffer+8, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[index]->damr->framesPerSample), 1);
1329 if (handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index])
1331 if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index]->damr)
1336 *decspecinfosize = 9;
1337 if (buffersize < *decspecinfosize)
1339 return MP4_BUFFER_TOO_SMALL;
1342 mp4memcpy(buffer, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index]->damr->vendor), 4);
1343 mp4memcpy(buffer+4, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index]->damr->decoderVersion), 1);
1344 mp4memcpy(buffer+5, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index]->damr->modeSet), 2);
1345 mp4memcpy(buffer+7, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index]->damr->modeChangePeriod), 1);
1346 mp4memcpy(buffer+8, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[index]->damr->framesPerSample), 1);
1349 if (handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[index])
1351 if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[index]->dqcp)
1356 *decspecinfosize = 6;
1357 if (buffersize < *decspecinfosize)
1359 return MP4_BUFFER_TOO_SMALL;
1362 mp4memcpy(buffer, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[index]->dqcp->vendor), 4);
1363 mp4memcpy(buffer+4, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[index]->dqcp->decoderVersion), 1);
1364 mp4memcpy(buffer+5, &(handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[index]->dqcp->framesPerSample), 1);
1375 extern EXPORT_C MP4Err MP4ParseGetNextVideoTimestamp(MP4Handle apihandle,
1377 mp4_u32 *timestamp2)
1379 MP4HandleImp handle = (MP4HandleImp)apihandle;
1381 if (!handle->metaDataComplete)
1383 switch (metaDataAvailable(handle))
1387 return MP4_NOT_AVAILABLE;
1390 handle->cafError = KErrNone;
1391 if (readMetaData(handle) < 0)
1393 // Reading of meta data failed, so free up any allocated memory
1394 freeFTYP(handle->ftyp);
1395 handle->ftyp = NULL;
1396 freeMOOV(handle->moov);
1397 handle->moov = NULL;
1399 if ( handle->cafError != KErrNone )
1401 // if CAF/DRM caused the error return it instead of generic errorcode.
1402 return handle->cafError;
1406 return MP4_INVALID_INPUT_STREAM;
1409 handle->metaDataComplete = MP4TRUE;
1413 // Reading of FTYP meta data failed, so free up any allocated memory
1414 freeFTYP(handle->ftyp);
1415 handle->ftyp = NULL;
1427 if (!handle->moov->trakVideo)
1430 if (!handle->moov->trakVideo->mdia)
1433 if (handle->videoLast)
1434 return MP4_END_OF_VIDEO;
1436 if (convertVideoSampleToTime(handle, handle->moov->trakVideo->mdia, timestamp, timestamp2) < 0)
1439 switch (advanceVideoFrame(handle, handle->moov->trakVideo))
1444 handle->videoLast = MP4TRUE;
1453 extern EXPORT_C MP4Err MP4ParseIsStreamable(MP4Handle apihandle)
1455 MP4HandleImp handle = (MP4HandleImp)apihandle;
1457 if (!handle->metaDataComplete)
1459 switch (metaDataAvailable(handle))
1463 return MP4_NOT_AVAILABLE;
1466 handle->cafError = KErrNone;
1467 if (readMetaData(handle) < 0)
1469 // Reading of meta data failed, so free up any allocated memory
1470 freeFTYP(handle->ftyp);
1471 handle->ftyp = NULL;
1472 freeMOOV(handle->moov);
1473 handle->moov = NULL;
1475 if ( handle->cafError != KErrNone )
1477 // if CAF/DRM caused the error return it instead of generic errorcode.
1478 return handle->cafError;
1482 return MP4_INVALID_INPUT_STREAM;
1485 handle->metaDataComplete = MP4TRUE;
1489 // Reading of FTYP meta data failed, so free up any allocated memory
1490 freeFTYP(handle->ftyp);
1491 handle->ftyp = NULL;
1500 /* There is no audio nor video */
1502 if (!handle->audioSampleNum && !handle->videoSampleNum)
1505 /* There is audio, but no video */
1507 if (handle->audioSampleNum && !handle->videoSampleNum)
1512 if (!handle->moov->trakAudio)
1515 if (!handle->moov->trakAudio->mdia)
1518 if (!handle->moov->trakAudio->mdia->minf)
1521 if (!handle->moov->trakAudio->mdia->minf->stbl)
1524 if (!handle->moov->trakAudio->mdia->minf->stbl->stco)
1527 if (handle->moov->trakAudio->mdia->minf->stbl->stco->entryCount < 2)
1530 if (getChunkOffset(handle->moov->trakAudio->mdia->minf->stbl, 0) <
1531 getChunkOffset(handle->moov->trakAudio->mdia->minf->stbl, 1))
1534 return MP4_NOT_STREAMABLE;
1537 /* There is video, but no audio */
1539 if (handle->videoSampleNum && !handle->audioSampleNum)
1544 if (!handle->moov->trakVideo)
1547 if (!handle->moov->trakVideo->mdia)
1550 if (!handle->moov->trakVideo->mdia->minf)
1553 if (!handle->moov->trakVideo->mdia->minf->stbl)
1556 if (!handle->moov->trakVideo->mdia->minf->stbl->stco)
1559 if (handle->moov->trakVideo->mdia->minf->stbl->stco->entryCount < 2)
1562 if (getChunkOffset(handle->moov->trakVideo->mdia->minf->stbl, 0) <
1563 getChunkOffset(handle->moov->trakVideo->mdia->minf->stbl, 1))
1566 return MP4_NOT_STREAMABLE;
1569 /* There are both audio and video */
1571 if (handle->videoSampleNum && handle->audioSampleNum)
1579 if (!handle->moov->trakAudio)
1582 if (!handle->moov->trakAudio->mdia)
1585 if (!handle->moov->trakAudio->mdia->minf)
1588 if (!handle->moov->trakAudio->mdia->minf->stbl)
1591 if (!handle->moov->trakAudio->mdia->minf->stbl->stco)
1594 if (!handle->moov->trakAudio->mdia->minf->stbl->stco->entryCount)
1597 if (!handle->moov->trakVideo)
1600 if (!handle->moov->trakVideo->mdia)
1603 if (!handle->moov->trakVideo->mdia->minf)
1606 if (!handle->moov->trakVideo->mdia->minf->stbl)
1609 if (!handle->moov->trakVideo->mdia->minf->stbl->stco)
1612 if (!handle->moov->trakVideo->mdia->minf->stbl->stco->entryCount)
1615 diff = getChunkOffset(handle->moov->trakAudio->mdia->minf->stbl, 0) -
1616 getChunkOffset(handle->moov->trakVideo->mdia->minf->stbl, 0);
1618 /* If the distance between 1st audio and video chunk offsets is larger
1619 than 50000, MP4 is not streamable. */
1621 if (diff < -50000 || diff > 50000)
1622 return MP4_NOT_STREAMABLE;
1630 extern EXPORT_C MP4Err MP4ParseSeek(MP4Handle apihandle,
1632 mp4_u32 *audioPosition,
1633 mp4_u32 *videoPosition,
1636 MP4HandleImp handle = (MP4HandleImp)apihandle;
1637 if (!handle->metaDataComplete)
1639 switch (metaDataAvailable(handle))
1642 return MP4_NOT_AVAILABLE;
1644 handle->cafError = KErrNone;
1645 if (readMetaData(handle) < 0)
1647 // Reading of meta data failed, so free up any allocated memory
1648 freeFTYP(handle->ftyp);
1649 handle->ftyp = NULL;
1650 freeMOOV(handle->moov);
1651 handle->moov = NULL;
1653 if ( handle->cafError != KErrNone )
1654 {// if CAF/DRM caused the error return it instead of generic errorcode.
1655 return handle->cafError;
1659 return MP4_INVALID_INPUT_STREAM;
1662 handle->metaDataComplete = MP4TRUE;
1666 // Reading of FTYP meta data failed, so free up any allocated memory
1667 freeFTYP(handle->ftyp);
1668 handle->ftyp = NULL;
1680 handle->audioLast = MP4FALSE;
1681 handle->videoLast = MP4FALSE;
1683 /* There is no audio nor video */
1685 if (!handle->audioSampleNum && !handle->videoSampleNum)
1688 /* There is only audio */
1690 if (handle->audioSampleNum && !handle->videoSampleNum)
1692 mp4_u32 audioSample;
1694 if (!handle->moov->trakAudio)
1696 if (!handle->moov->trakAudio->mdia)
1699 if (convertTimeToSample(handle, handle->moov->trakAudio, position, &audioSample) < 0)
1700 return MP4_CANT_SEEK;
1702 if (goToAudioSample(handle, handle->moov->trakAudio, audioSample) < 0)
1705 if (convertAudioSampleToTime(handle, handle->moov->trakAudio->mdia, audioPosition, NULL) < 0)
1710 handle->lastAccessedPosInFile = handle->audioSampleOffset + handle->audioSampleSize - 1;
1714 // check if there is enough data in the buffers
1715 if (handle->audioSampleOffset + handle->audioSampleSize - 1 > getCumulativeBufferedBytes(handle))
1717 if (handle->LastWriteDataCalled)
1719 // user has indicated that no more data will be available
1720 return MP4_CANT_SEEK;
1724 // signal to user that more data needed
1725 return MP4_NOT_AVAILABLE;
1728 else if (handle->audioSampleOffset < handle->absPosition)
1730 handle->absPosition = handle->audioSampleOffset;
1737 /* There is only video */
1738 if (handle->videoSampleNum && !handle->audioSampleNum)
1740 mp4_u32 videoSample;
1741 mp4_u32 newVideoSample;
1743 if (!handle->moov->trakVideo)
1745 if (!handle->moov->trakVideo->mdia)
1748 if (convertTimeToSample(handle, handle->moov->trakVideo, position, &videoSample) < 0)
1749 return MP4_CANT_SEEK;
1753 if (findVideoKeyFrame(handle, handle->moov->trakVideo, videoSample, &newVideoSample) < 0)
1755 return MP4_CANT_SEEK;
1757 videoSample = newVideoSample;
1760 if (goToVideoSample(handle, handle->moov->trakVideo, videoSample) < 0)
1765 if (convertVideoSampleToTime(handle, handle->moov->trakVideo->mdia, videoPosition, NULL) < 0)
1772 handle->lastAccessedPosInFile = handle->videoFrameOffset + handle->videoFrameSize - 1;
1774 else // input is a stream
1776 // check if there is enough data in the buffers
1777 if (handle->videoFrameOffset + handle->videoFrameSize > getCumulativeBufferedBytes(handle))
1779 if (handle->LastWriteDataCalled)
1781 // user has indicated that no more data will be available
1782 return MP4_CANT_SEEK;
1786 // signal to user that more data needed
1787 return MP4_NOT_AVAILABLE;
1792 handle->absPosition = handle->videoFrameOffset;
1799 /* There is audio and video */
1801 if (handle->videoSampleNum && handle->audioSampleNum)
1803 mp4_u32 audioSample;
1804 mp4_u32 videoSample;
1805 mp4_u32 newVideoSample;
1808 if (!handle->moov->trakAudio)
1810 if (!handle->moov->trakAudio->mdia)
1812 if (!handle->moov->trakVideo)
1814 if (!handle->moov->trakVideo->mdia)
1817 if (convertTimeToSample(handle, handle->moov->trakVideo, position, &videoSample) < 0)
1818 return MP4_CANT_SEEK;
1822 if (findVideoKeyFrame(handle, handle->moov->trakVideo, videoSample, &newVideoSample) < 0)
1823 return MP4_CANT_SEEK;
1825 videoSample = newVideoSample;
1828 if (goToVideoSample(handle, handle->moov->trakVideo, videoSample) < 0)
1831 if (convertVideoSampleToTime(handle, handle->moov->trakVideo->mdia, videoPosition, NULL) < 0)
1836 handle->lastAccessedPosInFile = handle->videoFrameOffset + handle->videoFrameSize - 1;
1838 else // input is a stream
1840 // check if there is enough data in the buffers
1841 if (handle->videoFrameOffset + handle->videoFrameSize > getCumulativeBufferedBytes(handle))
1843 if (handle->LastWriteDataCalled)
1845 // user has indicated that no more data will be available
1846 return MP4_CANT_SEEK;
1850 // signal to user that more data needed
1851 return MP4_NOT_AVAILABLE;
1856 handle->absPosition = handle->videoFrameOffset;
1862 if (convertTimeToSample(handle, handle->moov->trakAudio, *videoPosition, &audioSample) < 0)
1863 return MP4_CANT_SEEK;
1865 if (goToAudioSample(handle, handle->moov->trakAudio, audioSample) < 0)
1868 if (convertAudioSampleToTime(handle, handle->moov->trakAudio->mdia, audioPosition, NULL) < 0)
1873 if (handle->audioSampleOffset + handle->audioSampleSize - 1 > handle->lastAccessedPosInFile)
1875 handle->lastAccessedPosInFile = handle->audioSampleOffset + handle->audioSampleSize - 1;
1878 else // input is a stream
1880 // check if there is enough data in the buffers
1881 if (handle->audioSampleOffset + handle->audioSampleSize - 1 > getCumulativeBufferedBytes(handle))
1883 if (handle->LastWriteDataCalled)
1885 // user has indicated that no more data will be available
1886 return MP4_CANT_SEEK;
1890 // signal to user that more data needed
1891 return MP4_NOT_AVAILABLE;
1894 else if (handle->audioSampleOffset < handle->absPosition)
1896 handle->absPosition = handle->audioSampleOffset;
1906 extern EXPORT_C MP4Err MP4ParseIsFrameAvailable(MP4Handle apihandle,
1909 MP4HandleImp handle = (MP4HandleImp)apihandle;
1910 if (!handle->metaDataComplete)
1912 switch (metaDataAvailable(handle))
1915 return MP4_NOT_AVAILABLE;
1917 handle->cafError = KErrNone;
1918 if (readMetaData(handle) < 0)
1920 // Reading of meta data failed, so free up any allocated memory
1921 freeFTYP(handle->ftyp);
1922 handle->ftyp = NULL;
1923 freeMOOV(handle->moov);
1924 handle->moov = NULL;
1926 if ( handle->cafError != KErrNone )
1928 // if CAF/DRM caused the error return it instead of generic errorcode.
1930 return handle->cafError;
1934 return MP4_INVALID_INPUT_STREAM;
1937 handle->metaDataComplete = MP4TRUE;
1941 // Reading of FTYP meta data failed, so free up any allocated memory
1942 freeFTYP(handle->ftyp);
1943 handle->ftyp = NULL;
1952 switch (type & handle->type)
1954 case MP4_TYPE_MPEG4_VIDEO:
1955 case MP4_TYPE_H263_PROFILE_0:
1956 case MP4_TYPE_H263_PROFILE_3:
1957 case MP4_TYPE_AVC_PROFILE_BASELINE:
1958 case MP4_TYPE_AVC_PROFILE_MAIN:
1959 case MP4_TYPE_AVC_PROFILE_EXTENDED:
1960 case MP4_TYPE_AVC_PROFILE_HIGH:
1962 /* There is no frame available if last sample has been reached */
1964 if (handle->videoLast)
1965 return MP4_NO_REQUESTED_FRAME;
1967 /* Input in a file => it is available */
1972 /* If frame has been buffered, it is available */
1974 if (handle->videoFrameOffset + handle->videoFrameSize <=
1975 getCumulativeBufferedBytes(handle))
1978 return MP4_NOT_AVAILABLE;
1980 case MP4_TYPE_MPEG4_AUDIO:
1981 case MP4_TYPE_AMR_NB:
1982 case MP4_TYPE_AMR_WB:
1983 case MP4_TYPE_QCELP_13K:
1985 /* There is no frame available if last sample has been reached */
1987 if (handle->audioLast)
1988 return MP4_NO_REQUESTED_FRAME;
1990 /* Input in a file => it is available */
1995 /* If frame has been buffered, it is available */
1997 if (handle->audioSampleOffset + handle->audioSampleSize <=
1998 getCumulativeBufferedBytes(handle))
2001 return MP4_NOT_AVAILABLE;
2006 return MP4_NO_REQUESTED_FRAME;
2010 extern EXPORT_C MP4Err MP4ParseGetLastPosition(MP4Handle apihandle,
2013 return MP4ParseGetLastPosition64(apihandle, (mp4_u64 *)position);
2016 extern EXPORT_C MP4Err MP4ParseGetLastPosition64(MP4Handle apihandle,
2019 MP4HandleImp handle = (MP4HandleImp)apihandle;
2022 *position = handle->absPosition; // return the latest accessed absolute byte location of the stream.
2025 *position = handle->lastAccessedPosInFile;
2030 extern EXPORT_C MP4Err MP4ParseGetNumberOfVideoFrames(MP4Handle apihandle,
2031 mp4_u32 *numberOfFrames)
2033 MP4HandleImp handle = (MP4HandleImp)apihandle;
2034 if (!handle->metaDataComplete)
2036 switch (metaDataAvailable(handle))
2039 return MP4_NOT_AVAILABLE;
2041 handle->cafError = KErrNone;
2042 if (readMetaData(handle) < 0)
2044 // Reading of meta data failed, so free up any allocated memory
2045 freeFTYP(handle->ftyp);
2046 handle->ftyp = NULL;
2047 freeMOOV(handle->moov);
2048 handle->moov = NULL;
2050 if ( handle->cafError != KErrNone )
2051 {// if CAF/DRM caused the error return it instead of generic errorcode.
2052 return handle->cafError;
2056 return MP4_INVALID_INPUT_STREAM;
2059 handle->metaDataComplete = MP4TRUE;
2063 // Reading of FTYP meta data failed, so free up any allocated memory
2064 freeFTYP(handle->ftyp);
2065 handle->ftyp = NULL;
2077 if (handle->moov->trakVideo)
2079 if (!handle->moov->trakVideo->mdia)
2082 if (!handle->moov->trakVideo->mdia->minf)
2085 if (!handle->moov->trakVideo->mdia->minf->stbl)
2088 if (!handle->moov->trakVideo->mdia->minf->stbl->stsz)
2096 *numberOfFrames = handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount;
2100 extern EXPORT_C MP4Err MP4ParseGetVideoFrameSize(MP4Handle apihandle,
2104 MP4HandleImp handle = (MP4HandleImp)apihandle;
2105 if (!handle->metaDataComplete)
2107 switch (metaDataAvailable(handle))
2110 return MP4_NOT_AVAILABLE;
2112 handle->cafError = KErrNone;
2113 if (readMetaData(handle) < 0)
2115 // Reading of meta data failed, so free up any allocated memory
2116 freeFTYP(handle->ftyp);
2117 handle->ftyp = NULL;
2118 freeMOOV(handle->moov);
2119 handle->moov = NULL;
2121 if ( handle->cafError != KErrNone )
2122 {// if CAF/DRM caused the error return it instead of generic errorcode.
2123 return handle->cafError;
2127 return MP4_INVALID_INPUT_STREAM;
2130 handle->metaDataComplete = MP4TRUE;
2134 // Reading of FTYP meta data failed, so free up any allocated memory
2135 freeFTYP(handle->ftyp);
2136 handle->ftyp = NULL;
2148 if (handle->moov->trakVideo)
2150 if (!handle->moov->trakVideo->mdia)
2153 if (!handle->moov->trakVideo->mdia->minf)
2156 if (!handle->moov->trakVideo->mdia->minf->stbl)
2159 if (!handle->moov->trakVideo->mdia->minf->stbl->stsz)
2162 // ensure the index entered is within bound
2163 if (index >= handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount)
2171 *frameSize = handle->moov->trakVideo->mdia->minf->stbl->stsz->entrySize[index];
2175 extern EXPORT_C MP4Err MP4ParseGetVideoFrameStartTime(MP4Handle apihandle,
2178 mp4_u32 *timestampms)
2183 mp4_u32 videoSampleNumber = index+1;
2185 MP4HandleImp handle = (MP4HandleImp)apihandle;
2186 if (!handle->metaDataComplete)
2188 switch (metaDataAvailable(handle))
2191 return MP4_NOT_AVAILABLE;
2193 handle->cafError = KErrNone;
2194 if (readMetaData(handle) < 0)
2196 // Reading of meta data failed, so free up any allocated memory
2197 freeFTYP(handle->ftyp);
2198 handle->ftyp = NULL;
2199 freeMOOV(handle->moov);
2200 handle->moov = NULL;
2202 if ( handle->cafError != KErrNone )
2203 {// if CAF/DRM caused the error return it instead of generic errorcode.
2204 return handle->cafError;
2208 return MP4_INVALID_INPUT_STREAM;
2211 handle->metaDataComplete = MP4TRUE;
2215 // Reading of FTYP meta data failed, so free up any allocated memory
2216 freeFTYP(handle->ftyp);
2217 handle->ftyp = NULL;
2231 if (handle->moov->trakVideo)
2233 if (!handle->moov->trakVideo->mdia)
2236 if (!handle->moov->trakVideo->mdia->minf)
2239 if (!handle->moov->trakVideo->mdia->minf->stbl)
2242 if (!handle->moov->trakVideo->mdia->minf->stbl->stts)
2252 if (sample + handle->moov->trakVideo->mdia->minf->stbl->stts->sampleCount[entry] < videoSampleNumber)
2254 sample += handle->moov->trakVideo->mdia->minf->stbl->stts->sampleCount[entry];
2255 tmptime += (handle->moov->trakVideo->mdia->minf->stbl->stts->sampleCount[entry] *
2256 handle->moov->trakVideo->mdia->minf->stbl->stts->sampleDelta[entry]);
2258 if (entry == handle->moov->trakVideo->mdia->minf->stbl->stts->entryCount)
2263 tmptime += ((videoSampleNumber - sample - 1) * handle->moov->trakVideo->mdia->minf->stbl->stts->sampleDelta[entry]);
2267 if (handle->moov->trakVideo->mdia->mdhd->timeScale == 0)
2272 *timestamp = tmptime;
2274 *timestampms =(mp4_u32)((mp4_double)tmptime * (mp4_double)1000 /
2275 (mp4_double)handle->moov->trakVideo->mdia->mdhd->timeScale + (mp4_double)0.5);
2280 extern EXPORT_C MP4Err MP4ParseGetVideoFrameType(MP4Handle apihandle,
2282 mp4_bool *frametype)
2285 mp4_u32 videoSampleNumber = index+1;
2286 mp4_bool keyFrame = MP4FALSE;
2288 MP4HandleImp handle = (MP4HandleImp)apihandle;
2289 if (!handle->metaDataComplete)
2291 switch (metaDataAvailable(handle))
2294 return MP4_NOT_AVAILABLE;
2296 handle->cafError = KErrNone;
2297 if (readMetaData(handle) < 0)
2299 // Reading of meta data failed, so free up any allocated memory
2300 freeFTYP(handle->ftyp);
2301 handle->ftyp = NULL;
2302 freeMOOV(handle->moov);
2303 handle->moov = NULL;
2305 if ( handle->cafError != KErrNone )
2306 {// if CAF/DRM caused the error return it instead of generic errorcode.
2307 return handle->cafError;
2311 return MP4_INVALID_INPUT_STREAM;
2314 handle->metaDataComplete = MP4TRUE;
2318 // Reading of FTYP meta data failed, so free up any allocated memory
2319 freeFTYP(handle->ftyp);
2320 handle->ftyp = NULL;
2332 if (handle->moov->trakVideo)
2334 if (!handle->moov->trakVideo->mdia)
2337 if (!handle->moov->trakVideo->mdia->minf)
2340 if (!handle->moov->trakVideo->mdia->minf->stbl)
2343 if (!handle->moov->trakVideo->mdia->minf->stbl->stss)
2346 // if the video frame index is out of bounds
2347 if (!handle->moov->trakVideo->mdia->minf->stbl->stsz ||
2348 videoSampleNumber > handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount)
2356 for (i=0; i < handle->moov->trakVideo->mdia->minf->stbl->stss->entryCount; i++)
2358 if (handle->moov->trakVideo->mdia->minf->stbl->stss->sampleNumber[i] == videoSampleNumber)
2365 *frametype = keyFrame;
2369 extern EXPORT_C MP4Err MP4ParseGetVideoSampleEntryIndex(MP4Handle apihandle, mp4_u32 *videosampleentryindex)
2371 MP4HandleImp handle = (MP4HandleImp)apihandle;
2372 if (!handle->metaDataComplete)
2374 switch (metaDataAvailable(handle))
2377 return MP4_NOT_AVAILABLE;
2379 handle->cafError = KErrNone;
2380 if (readMetaData(handle) < 0)
2382 // Reading of meta data failed, so free up any allocated memory
2383 freeFTYP(handle->ftyp);
2384 handle->ftyp = NULL;
2385 freeMOOV(handle->moov);
2386 handle->moov = NULL;
2388 if ( handle->cafError != KErrNone )
2389 {// if CAF/DRM caused the error return it instead of generic errorcode.
2390 return handle->cafError;
2394 return MP4_INVALID_INPUT_STREAM;
2397 handle->metaDataComplete = MP4TRUE;
2401 // Reading of FTYP meta data failed, so free up any allocated memory
2402 freeFTYP(handle->ftyp);
2403 handle->ftyp = NULL;
2412 if (!handle->moov->trakVideo)
2414 if (!handle->moov->trakVideo->mdia)
2417 if (handle->videoSampleEntryIndex == 0) /* can't be zero. Sample Entry index must be at least 1*/
2420 *videosampleentryindex = handle->videoSampleEntryIndex;
2425 extern EXPORT_C MP4Err MP4ParseGetAudioSampleEntryIndex(MP4Handle apihandle, mp4_u32 *audiosampleentryindex)
2427 MP4HandleImp handle = (MP4HandleImp)apihandle;
2428 if (!handle->metaDataComplete)
2430 switch (metaDataAvailable(handle))
2433 return MP4_NOT_AVAILABLE;
2435 handle->cafError = KErrNone;
2436 if (readMetaData(handle) < 0)
2438 // Reading of meta data failed, so free up any allocated memory
2439 freeFTYP(handle->ftyp);
2440 handle->ftyp = NULL;
2441 freeMOOV(handle->moov);
2442 handle->moov = NULL;
2444 if ( handle->cafError != KErrNone )
2445 {// if CAF/DRM caused the error return it instead of generic errorcode.
2446 return handle->cafError;
2450 return MP4_INVALID_INPUT_STREAM;
2453 handle->metaDataComplete = MP4TRUE;
2457 // Reading of FTYP meta data failed, so free up any allocated memory
2458 freeFTYP(handle->ftyp);
2459 handle->ftyp = NULL;
2468 if (!handle->moov->trakAudio)
2470 if (!handle->moov->trakAudio->mdia)
2473 if (handle->audioSampleEntryIndex == 0) /* can't be zero. Sample Entry index must be at least 1*/
2476 *audiosampleentryindex = handle->audioSampleEntryIndex;
2481 extern EXPORT_C MP4Err MP4ParseGetQCELPStorageMode(MP4Handle apihandle, mp4_u8 *qcelpStorageMode)
2483 MP4HandleImp handle = (MP4HandleImp)apihandle;
2484 if (!handle->metaDataComplete)
2486 switch (metaDataAvailable(handle))
2489 return MP4_NOT_AVAILABLE;
2491 handle->cafError = KErrNone;
2492 if (readMetaData(handle) < 0)
2494 // Reading of meta data failed, so free up any allocated memory
2495 freeFTYP(handle->ftyp);
2496 handle->ftyp = NULL;
2497 freeMOOV(handle->moov);
2498 handle->moov = NULL;
2500 if ( handle->cafError != KErrNone )
2501 {// if CAF/DRM caused the error return it instead of generic errorcode.
2502 return handle->cafError;
2506 return MP4_INVALID_INPUT_STREAM;
2509 handle->metaDataComplete = MP4TRUE;
2513 // Reading of FTYP meta data failed, so free up any allocated memory
2514 freeFTYP(handle->ftyp);
2515 handle->ftyp = NULL;
2524 if (!handle->moov->trakAudio)
2526 if (!handle->moov->trakAudio->mdia)
2528 if (!(handle->type & MP4_TYPE_QCELP_13K))
2531 if(handle->qcelpStoredAsMPEGAudio)
2532 *qcelpStorageMode = 1;
2534 *qcelpStorageMode = 0;
2539 extern EXPORT_C MP4Err MP4GetVideoFrameProperties(MP4Handle apihandle,mp4_u32 startindex,mp4_u32 sizeofarray,TFrameInfoParameters* aFrameInfoArray)
2545 mp4_u32 videoSampleNumber = (startindex+sizeofarray)+1;
2549 mp4_u32 actualIndex;
2551 MP4HandleImp handle = (MP4HandleImp)apihandle;
2553 TBool sampleSyncTableExists = ETrue;
2554 if (!handle->metaDataComplete)
2556 switch (metaDataAvailable(handle))
2559 return MP4_NOT_AVAILABLE;
2561 handle->cafError = KErrNone;
2562 if (readMetaData(handle) < 0)
2564 // Reading of meta data failed, so free up any allocated memory
2565 freeFTYP(handle->ftyp);
2566 handle->ftyp = NULL;
2567 freeMOOV(handle->moov);
2568 handle->moov = NULL;
2570 if ( handle->cafError != KErrNone )
2571 {// if CAF/DRM caused the error return it instead of generic errorcode.
2572 return handle->cafError;
2576 return MP4_INVALID_INPUT_STREAM;
2579 handle->metaDataComplete = MP4TRUE;
2583 // Reading of FTYP meta data failed, so free up any allocated memory
2584 freeFTYP(handle->ftyp);
2585 handle->ftyp = NULL;
2598 if (handle->moov->trakVideo)
2600 if (!handle->moov->trakVideo->mdia)
2603 if (!handle->moov->trakVideo->mdia->minf)
2606 if (!handle->moov->trakVideo->mdia->minf->stbl)
2609 if (!handle->moov->trakVideo->mdia->minf->stbl->stsz) //for size
2612 if (!handle->moov->trakVideo->mdia->minf->stbl->stss) //for type
2614 // If sample sync table doesn't exist mark all frames as intra / random access point
2615 sampleSyncTableExists = EFalse;
2618 if (!handle->moov->trakVideo->mdia->minf->stbl->stts) //For timeStamp
2627 if (handle->moov->trakVideo->mdia->mdhd->timeScale == 0) //For timeStamp
2632 if((startindex+sizeofarray) > handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount) //more than number of frames
2637 if(aFrameInfoArray == NULL)
2639 return MP4_NO_OUTPUT_BUFFER;
2642 if ( sampleSyncTableExists )
2644 for (i=0; i < handle->moov->trakVideo->mdia->minf->stbl->stss->entryCount; i++) //set all types to true
2646 //because counting is stored from 1 but index from 0
2647 mp4_u32 currFrame = handle->moov->trakVideo->mdia->minf->stbl->stss->sampleNumber[i] - 1;
2649 if ((currFrame >= startindex) && (currFrame < (startindex + sizeofarray)))
2651 aFrameInfoArray[currFrame - startindex].iType = MP4TRUE;
2656 index=0; //initialize to beginning
2657 actualIndex=0;//array indexer
2661 if(index< videoSampleNumber)
2663 for(j=0;j<handle->moov->trakVideo->mdia->minf->stbl->stts->sampleCount[entry];j++)
2665 if(index >=startindex)
2667 //first initialize flag to false if not previously set to true.
2668 if(aFrameInfoArray[actualIndex].iType != MP4TRUE)
2670 aFrameInfoArray[actualIndex].iType = MP4FALSE;
2672 //aFrameInfoArray[index].iStartTime = tmptime + handle->moov->trakVideo->mdia->minf->stbl->stts->sampleDelta[entry];
2673 if(index==0) //so first frame of entire clip
2675 aFrameInfoArray[actualIndex].iStartTime =0;
2679 aFrameInfoArray[actualIndex].iStartTime = (mp4_u32)((mp4_double)tmptime * (mp4_double)1000 /
2680 (mp4_double)handle->moov->trakVideo->mdia->mdhd->timeScale + (mp4_double)0.5);
2682 aFrameInfoArray[actualIndex].iSize = handle->moov->trakVideo->mdia->minf->stbl->stsz->entrySize[index];
2683 // If sample sync table doesn't exist mark all frames as intra / random access point
2684 if (!sampleSyncTableExists)
2686 aFrameInfoArray[actualIndex].iType = MP4TRUE;
2688 actualIndex++; //point to next index in array
2690 tmptime += handle->moov->trakVideo->mdia->minf->stbl->stts->sampleDelta[entry];
2691 //Now insert size before incrementing index
2692 if(index == videoSampleNumber-2)
2696 if(index==videoSampleNumber-2)
2698 sample += handle->moov->trakVideo->mdia->minf->stbl->stts->sampleCount[entry];
2709 extern EXPORT_C MP4Err MP4ParseGetVideoClipProperties(MP4Handle apihandle, TVideoClipProperties& aVideoClipProperties)
2711 MP4HandleImp handle = (MP4HandleImp)apihandle;
2717 if (!handle->metaDataComplete)
2719 switch (metaDataAvailable(handle))
2722 return MP4_NOT_AVAILABLE;
2724 handle->cafError = KErrNone;
2725 if (readMetaData(handle) < 0)
2727 // Reading of meta data failed, so free up any allocated memory
2728 freeFTYP(handle->ftyp);
2729 handle->ftyp = NULL;
2730 freeMOOV(handle->moov);
2731 handle->moov = NULL;
2733 if ( handle->cafError != KErrNone )
2734 {// if CAF/DRM caused the error return it instead of generic errorcode.
2735 return handle->cafError;
2739 return MP4_INVALID_INPUT_STREAM;
2742 handle->metaDataComplete = MP4TRUE;
2746 // Reading of FTYP meta data failed, so free up any allocated memory
2747 freeFTYP(handle->ftyp);
2748 handle->ftyp = NULL;
2759 if (!handle->moov->trakVideo)
2761 if (!handle->moov->trakVideo->mdia)
2763 if (!handle->moov->trakVideo->mdia->minf)
2765 if (!handle->moov->trakVideo->mdia->minf->stbl)
2767 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd)
2770 /* Assume that the video type is the same for all sample entries. Just get the video type from the first one */
2771 if (handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0])
2773 if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->d263)
2776 if (handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->d263->h263Level)
2778 aVideoClipProperties.iH263Level = handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->d263->h263Level;
2792 extern EXPORT_C MP4Err MP4ParseGetUserDataAtom(MP4Handle apihandle,
2793 mp4_u8& udtaLocation,
2794 mp4_u32 udtaAtomType,
2796 mp4_u32& bufferSize,
2797 mp4_u32& atomIndex )
2800 mp4_u64 largesize = 0;
2802 mp4_i32 bytesread = 0;
2803 mp4_i32 totalbytesread = 0;
2804 MP4Err retError = MP4_OK;
2805 userDataAtom* udta = NULL;
2806 mp4_bool found = MP4FALSE;
2807 mp4_u32 foundIndex = 0;
2809 MP4HandleImp handle = (MP4HandleImp)apihandle;
2816 if (!handle->metaDataComplete)
2818 switch (metaDataAvailable(handle))
2821 return MP4_NOT_AVAILABLE;
2823 handle->cafError = KErrNone;
2824 if (readMetaData(handle) < 0)
2826 // Reading of meta data failed, so free up any allocated memory
2827 freeFTYP(handle->ftyp);
2828 handle->ftyp = NULL;
2829 freeMOOV(handle->moov);
2830 handle->moov = NULL;
2832 if ( handle->cafError != KErrNone )
2833 {// if CAF/DRM caused the error return it instead of generic errorcode.
2834 return handle->cafError;
2838 return MP4_INVALID_INPUT_STREAM;
2841 handle->metaDataComplete = MP4TRUE;
2845 // Reading of FTYP meta data failed, so free up any allocated memory
2846 freeFTYP(handle->ftyp);
2847 handle->ftyp = NULL;
2859 // Check where to read udta from.
2860 switch ( udtaLocation )
2864 retError = MP4_UDTA_NOT_FOUND;
2869 if ( !handle->moov->udta )
2871 retError = MP4_UDTA_NOT_FOUND;
2876 udta = handle->moov->udta;
2880 case MP4_UDTA_VIDEOTRAK:
2882 if ( !handle->moov->trakVideo )
2884 retError = MP4_UDTA_NOT_FOUND;
2887 if ( !handle->moov->trakVideo->udta )
2889 retError = MP4_UDTA_NOT_FOUND;
2893 udta = handle->moov->trakVideo->udta;
2897 case MP4_UDTA_AUDIOTRAK:
2899 if (!handle->moov->trakAudio)
2901 retError = MP4_UDTA_NOT_FOUND;
2904 if ( !handle->moov->trakAudio->udta )
2906 retError = MP4_UDTA_NOT_FOUND;
2910 udta = handle->moov->trakAudio->udta;
2916 retError = MP4_INVALID_TYPE;
2920 if ( retError == MP4_OK ) // valid UDTA found.
2922 if ( !udta->atomhdr )
2924 retError = MP4_UDTA_NOT_FOUND;
2926 if ( !udta->atomcontentloc || (udta->atomcontentsize == 0) )
2928 retError = MP4_UDTA_NOT_FOUND;
2931 // seek to UDTA atom in memory structure or file.
2932 if (handle->file) /* Input is in a file */
2934 if (seekFileAbs(handle, udta->atomcontentloc) != 0)
2935 return MP4_CANT_SEEK;
2939 handle->absPosition = udta->atomcontentloc;
2942 // search for wanted atom from UDTA and read it to buffer
2943 while ( totalbytesread < (mp4_i32)udta->atomcontentsize )
2945 if (peekData(handle, handle->buf, 16) < 0)
2948 size = u32endian(*((mp4_u32 *)handle->buf));
2949 type = u32endian(*((mp4_u32 *)(handle->buf+4)));
2951 if ( type == udtaAtomType )
2953 if ( atomIndex == foundIndex )
2957 largesize = u64endian(*((mp4_u64*)(handle->buf+8)));
2958 size = (mp4_u32)I64INT(largesize);
2960 if ( size > bufferSize )
2962 // Although the output buffer supplied by the caller is
2963 // not large enough to store the sub user atom's content, keep
2964 // parsing thru the whole user data to retrieve the highest index
2965 // to be returned thru the atomIndex parameter
2967 retError = MP4_OUTPUT_BUFFER_TOO_SMALL;
2968 bytesread = readUnknown(handle);
2974 bytesread = readData(handle, buffer, size);
2977 bufferSize = bytesread;
2980 totalbytesread += bytesread;
2986 bytesread = readUnknown(handle);
2989 totalbytesread += bytesread;
2995 bytesread = readUnknown(handle);
2998 totalbytesread += bytesread;
3003 if ( ( atomIndex > foundIndex ) || !found )
3005 retError = MP4_UDTA_NOT_FOUND;
3008 // fill how many wanted type atom there is in asked UDTA.
3011 atomIndex = foundIndex - 1;
3018 // fill udtaLocation
3019 udtaLocation = MP4_UDTA_NONE;
3021 if ( handle->moov->udta )
3023 udtaLocation |= MP4_UDTA_MOOV;
3025 if ( handle->moov->trakVideo )
3027 if ( handle->moov->trakVideo->udta )
3029 udtaLocation |= MP4_UDTA_VIDEOTRAK;
3032 if ( handle->moov->trakAudio )
3034 if ( handle->moov->trakAudio->udta )
3036 udtaLocation |= MP4_UDTA_AUDIOTRAK;
3043 extern EXPORT_C MP4Err MP4ParseNextVideoFrameDependencies(MP4Handle apihandle, mp4_u8* aDependsOn, mp4_u8* aIsDependentOn, mp4_u8* aHasRedundancy)
3045 MP4HandleImp handle = (MP4HandleImp)apihandle;
3052 if(!aDependsOn || !aIsDependentOn || !aHasRedundancy)
3054 return MP4_NO_OUTPUT_BUFFER;
3056 if (!handle->metaDataComplete)
3058 switch (metaDataAvailable(handle))
3061 return MP4_NOT_AVAILABLE;
3064 if (readMetaData(handle) < 0)
3066 // Reading of meta data failed, so free up any allocated memory
3067 freeFTYP(handle->ftyp);
3068 handle->ftyp = NULL;
3069 freeMOOV(handle->moov);
3070 handle->moov = NULL;
3072 return MP4_INVALID_INPUT_STREAM;
3075 handle->metaDataComplete = MP4TRUE;
3079 // Reading of FTYP meta data failed, so free up any allocated memory
3080 freeFTYP(handle->ftyp);
3081 handle->ftyp = NULL;
3090 if (determineVideoType(handle, &type) < 0)
3094 if( !isAvcVideo(type) )
3096 *aDependsOn = 0; // Unknown
3097 *aIsDependentOn = 0; // Unknown
3098 *aHasRedundancy = 0; // Unknown
3104 if (!handle->moov->trakVideo)
3106 if (!handle->moov->trakVideo->mdia)
3108 if (!handle->moov->trakVideo->mdia->minf)
3110 if (!handle->moov->trakVideo->mdia->minf->stbl)
3112 if (!handle->moov->trakVideo->mdia->minf->stbl->sdtp)
3114 *aDependsOn = 0; // Unknown
3115 *aIsDependentOn = 0; // Unknown
3116 *aHasRedundancy = 0; // Unknown
3119 if (!handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep)
3124 if (handle->videoSampleNum <= 0)
3129 if(handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep[handle->videoSampleNum - 1].sDependsOn > 2 ||
3130 handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep[handle->videoSampleNum - 1].sIsDependentOn > 2 ||
3131 handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep[handle->videoSampleNum - 1].sHasRedundancy > 2)
3135 *aDependsOn = handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep[handle->videoSampleNum - 1].sDependsOn;
3136 *aIsDependentOn = handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep[handle->videoSampleNum - 1].sIsDependentOn;
3137 *aHasRedundancy = handle->moov->trakVideo->mdia->minf->stbl->sdtp->dep[handle->videoSampleNum - 1].sHasRedundancy;
3141 extern EXPORT_C MP4Err MP4ParseReadAudioFramesAsync(MP4Handle apihandle, M3GPMP4LibAsyncObserver* aObserver, mp4_u8 *buffer, mp4_u32* buffersize)
3143 MP4HandleImp handle = (MP4HandleImp)apihandle;
3147 // async operation is only supported for files.
3148 return MP4_FILE_ERROR;
3151 if (!handle->metaDataComplete)
3153 switch (metaDataAvailable(handle))
3156 return MP4_NOT_AVAILABLE;
3158 handle->cafError = KErrNone;
3159 if (readMetaData(handle) < 0)
3161 // Reading of meta data failed, so free up any allocated memory
3162 freeFTYP(handle->ftyp);
3163 handle->ftyp = NULL;
3164 freeMOOV(handle->moov);
3165 handle->moov = NULL;
3167 if ( handle->cafError != KErrNone )
3169 // if CAF/DRM caused the error return it instead of generic errorcode.
3170 return handle->cafError;
3174 return MP4_INVALID_INPUT_STREAM;
3177 handle->metaDataComplete = MP4TRUE;
3181 // Reading of FTYP meta data failed, so free up any allocated memory
3182 freeFTYP(handle->ftyp);
3183 handle->ftyp = NULL;
3192 handle->asyncObserver = aObserver;
3194 /* Is audio available? */
3195 if (!((handle->type & MP4_TYPE_MPEG4_AUDIO) ||
3196 (handle->type & MP4_TYPE_AMR_NB) ||
3197 (handle->type & MP4_TYPE_AMR_WB) ||
3198 (handle->type & MP4_TYPE_QCELP_13K)))
3201 /* Are there samples left? */
3202 if (handle->audioLast)
3203 return MP4_NO_FRAME;
3207 if (!handle->moov->trakAudio)
3210 switch (fetchAudioSampleAsync(handle, handle->moov->trakAudio, buffer, buffersize))
3215 return MP4_BUFFER_TOO_SMALL;
3217 return MP4_INVALID_INPUT_STREAM;
3218 case MP4_OUT_OF_MEMORY:
3219 return MP4_OUT_OF_MEMORY;
3226 extern EXPORT_C MP4Err MP4ParseReadVideoFrameAsync(MP4Handle apihandle,
3227 M3GPMP4LibAsyncObserver* aObserver,
3229 mp4_u32* buffersize)
3231 MP4HandleImp handle = (MP4HandleImp)apihandle;
3235 // async operation is only supported for files.
3236 return MP4_FILE_ERROR;
3239 if (!handle->metaDataComplete)
3241 switch (metaDataAvailable(handle))
3245 return MP4_NOT_AVAILABLE;
3248 handle->cafError = KErrNone;
3249 if (readMetaData(handle) < 0)
3251 // Reading of meta data failed, so free up any allocated memory
3252 freeFTYP(handle->ftyp);
3253 handle->ftyp = NULL;
3254 freeMOOV(handle->moov);
3255 handle->moov = NULL;
3257 if ( handle->cafError != KErrNone )
3259 // if CAF/DRM caused the error return it instead of generic errorcode.
3260 return handle->cafError;
3264 return MP4_INVALID_INPUT_STREAM;
3267 handle->metaDataComplete = MP4TRUE;
3271 // Reading of FTYP meta data failed, so free up any allocated memory
3272 freeFTYP(handle->ftyp);
3273 handle->ftyp = NULL;
3282 /* Is video available? */
3283 if (!((handle->type & MP4_TYPE_MPEG4_VIDEO) ||
3284 (handle->type & MP4_TYPE_H263_PROFILE_0) ||
3285 (handle->type & MP4_TYPE_H263_PROFILE_3) ||
3286 containsAvcVideo( handle->type ) ))
3289 /* Are there samples left? */
3290 if (handle->videoLast)
3291 return MP4_NO_FRAME;
3293 handle->asyncObserver = aObserver;
3297 if (!handle->moov->trakVideo)
3300 switch (fetchVideoFrameAsync(handle, handle->moov->trakVideo, buffer, buffersize ))
3305 return MP4_BUFFER_TOO_SMALL;
3307 return MP4_NOT_AVAILABLE;
3309 return MP4_INVALID_INPUT_STREAM;
3310 case MP4_OUT_OF_MEMORY:
3311 return MP4_OUT_OF_MEMORY;
3319 extern EXPORT_C void MP4CancelReadFrame(MP4Handle ahandle)
3321 MP4HandleImp handle = (MP4HandleImp)ahandle;
3323 if (handle->asyncReader)
3325 handle->asyncReader->Cancel();
3329 extern EXPORT_C MP4Err MP4ParseGetID32Location(MP4Handle apihandle, mp4_u32& location)
3331 MP4HandleImp handle = (MP4HandleImp)apihandle;
3338 if (!handle->metaDataComplete)
3340 switch (metaDataAvailable(handle))
3343 return MP4_NOT_AVAILABLE;
3345 handle->cafError = KErrNone;
3346 if (readMetaData(handle) < 0)
3348 // Reading of meta data failed, so free up any allocated memory
3349 freeFTYP(handle->ftyp);
3350 handle->ftyp = NULL;
3351 freeMOOV(handle->moov);
3352 handle->moov = NULL;
3353 if (handle->cafError != KErrNone)
3354 {// if CAF/DRM caused the error return it instead of generic errorcode.
3355 return handle->cafError;
3359 return MP4_INVALID_INPUT_STREAM;
3362 handle->metaDataComplete = MP4TRUE;
3366 // Reading of FTYP meta data failed, so free up any allocated memory
3367 freeFTYP(handle->ftyp);
3368 handle->ftyp = NULL;
3380 metaAtom* meta = handle->moov->meta;
3382 return MP4_NOT_AVAILABLE;
3385 return MP4_NOT_AVAILABLE;
3389 location = meta->ID32->atomcontentloc;
3393 return MP4_NOT_AVAILABLE;