c8adc2055ee0bcffc82573863bd43933a3a66abd
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_formats.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "mm_file_debug.h"
26 #include "mm_file_format_private.h"
27 #include "mm_file_utils.h"
28
29 #define _MMF_FILE_FILEEXT_MAX 128
30
31 #define MMFILE_EXT_MP4          0x6D7034
32 #define MMFILE_EXT_MPEG4        0x6D70656734
33 #define MMFILE_EXT_M4A          0x6D3461
34 #define MMFILE_EXT_MPG          0x6D7067
35 #define MMFILE_EXT_MPG4         0x6D706734
36 #define MMFILE_EXT_M4V          0x6D3476
37 #define MMFILE_EXT_3GP          0x336770
38 #define MMFILE_EXT_AMR          0x616D72
39 #define MMFILE_EXT_AWB          0x617762
40 #define MMFILE_EXT_WAV          0x776176
41 #define MMFILE_EXT_MID          0x6D6964
42 #define MMFILE_EXT_MIDI         0x6D696D69
43 #define MMFILE_EXT_SPM          0x73706D
44 #define MMFILE_EXT_MP3          0x6D7033
45 #define MMFILE_EXT_AAC          0x616163
46 #define MMFILE_EXT_XMF          0x786D66
47 #define MMFILE_EXT_MXMF         0x6D786D66
48 #define MMFILE_EXT_MMF          0x6D6D66
49 #define MMFILE_EXT_MA2          0x6D6132
50 #define MMFILE_EXT_IMY          0x696D79
51 #define MMFILE_EXT_AVI          0x617669
52 #define MMFILE_EXT_DIVX         0x64697678
53 #define MMFILE_EXT_ASF          0x617366
54 #define MMFILE_EXT_ASX          0x617378
55 #define MMFILE_EXT_WMA          0x776D61
56 #define MMFILE_EXT_WMV          0x776D76
57 #define MMFILE_EXT_OGG          0x6F6767
58 #define MMFILE_EXT_MKV          0x6D6B76
59 #define MMFILE_EXT_MKA          0x6D6B61
60 #define MMFILE_EXT_MOV          0x6D6F76
61 #define MMFILE_EXT_FLAC         0x666C6163
62 #define MMFILE_EXT_FLV          0x666C76
63 #define MMFILE_EXT_AIF          0x616966
64 #define MMFILE_EXT_AIFF         0x61696666
65 #define MMFILE_EXT_RMVB         0x726D7662
66 #define MMFILE_EXT_RM           0x726D
67 #define MMFILE_EXT_M2TS         0x6D327473
68 #define MMFILE_EXT_MTS          0x6D7473
69 #define MMFILE_EXT_TS           0x7473
70 #define MMFILE_EXT_TP           0x7470
71 #define MMFILE_EXT_MPEG         0x6D706567
72 #define MMFILE_EXT_WEBM         0x7765626D
73 #define MMFILE_EXT_TTS          0x747473
74 #define MMFILE_EXT_TRP          0x747270
75 #define MMFILE_EXT_3M           0x336D
76 #define MMFILE_EXT_26L          0x32366C
77 #define MMFILE_EXT_264          0x323634
78
79 const struct {
80         int (*Open)(MMFileFormatContext *fileContext);
81         int (*Valid)(MMFileIOHandle *pFileIO, const char *mmfileuri, int mp3FrameCnt);
82 } MMFileFunc[MM_FILE_FORMAT_NUM + 1] = {
83         {mmfile_format_open_ffmpg, MMFileFormatIsValidMP4},                     /* 3GP */
84         {mmfile_format_open_ffmpg, MMFileFormatIsValidASF},                     /* ASF */
85         {mmfile_format_open_ffmpg, MMFileFormatIsValidAVI},                     /* AVI */
86         {mmfile_format_open_ffmpg, MMFileFormatIsValidMatroska},        /* MATROSAK */
87         {mmfile_format_open_ffmpg, MMFileFormatIsValidMP4},                     /* MP4 */
88         {mmfile_format_open_ffmpg, MMFileFormatIsValidOGG},                     /* OGG */
89         {NULL, NULL},                                                                                           /* NUT */
90         {mmfile_format_open_ffmpg, MMFileFormatIsValidMP4},                     /* QT */
91         {mmfile_format_open_ffmpg, MMFileFormatIsValidREAL},            /* REAL */
92         {mmfile_format_open_amr,   MMFileFormatIsValidAMR},                     /* AMR */
93         {mmfile_format_open_aac,   MMFileFormatIsValidAAC},                     /* AAC */
94         {mmfile_format_open_mp3,   MMFileFormatIsValidMP3},                     /* MP3 */
95         {mmfile_format_open_ffmpg, MMFileFormatIsValidAIFF},                    /* AIFF */
96         {NULL, NULL},                                                                                           /* AU */
97         {mmfile_format_open_wav,   MMFileFormatIsValidWAV},                     /* WAV */
98         {mmfile_format_open_mid,   MMFileFormatIsValidMID},                     /* MID */
99         {mmfile_format_open_mmf,   MMFileFormatIsValidMMF},                     /* MMF */
100         {mmfile_format_open_ffmpg, MMFileFormatIsValidAVI},                     /* DIVX */
101         {mmfile_format_open_ffmpg, MMFileFormatIsValidFLV},                     /* FLV */
102         {NULL, NULL},                                                                                           /* VOB */
103         {mmfile_format_open_imy,   MMFileFormatIsValidIMY},                     /* IMY */
104         {mmfile_format_open_ffmpg, MMFileFormatIsValidWMA},                     /* WMA */
105         {mmfile_format_open_ffmpg, MMFileFormatIsValidWMV},                     /* WMV */
106         {NULL, NULL},                                                                                           /* JPG */
107         {mmfile_format_open_ffmpg, MMFileFormatIsValidFLAC},            /* FLAC */
108         {mmfile_format_open_ffmpg, MMFileFormatIsValidMPEGTS},          /* MPEG-TS */
109         {mmfile_format_open_ffmpg, MMFileFormatIsValidMPEGPS},          /* MPEG-PS */
110         {mmfile_format_open_ffmpg, MMFileFormatIsValidMPEGVIDEO},       /* MPEG 1 VIDEO */
111         {mmfile_format_open_ffmpg, MMFileFormatIsValidMPEGAUDIO},       /* MPEG 1 AUDIO */
112         {NULL, NULL}
113 };
114
115 static int _CleanupFrameContext(MMFileFormatContext *formatContext, bool clean_all)
116 {
117         if (formatContext) {
118
119                 if (formatContext->ReadStream)  formatContext->ReadStream       = NULL;
120                 if (formatContext->ReadFrame)           formatContext->ReadFrame        = NULL;
121                 if (formatContext->ReadTag)             formatContext->ReadTag          = NULL;
122                 if (formatContext->Close)                       formatContext->Close                    = NULL;
123
124                 if (formatContext->uriFileName)         mmfile_free(formatContext->uriFileName);
125                 if (formatContext->title)                               mmfile_free(formatContext->title);
126                 if (formatContext->artist)                              mmfile_free(formatContext->artist);
127                 if (formatContext->author)                      mmfile_free(formatContext->author);
128                 if (formatContext->composer)                    mmfile_free(formatContext->composer);
129                 if (formatContext->album)                               mmfile_free(formatContext->album);
130                 if (formatContext->album_artist)                mmfile_free(formatContext->album_artist);
131                 if (formatContext->copyright)                   mmfile_free(formatContext->copyright);
132                 if (formatContext->description)                 mmfile_free(formatContext->description);
133                 if (formatContext->comment)                     mmfile_free(formatContext->comment);
134                 if (formatContext->genre)                               mmfile_free(formatContext->genre);
135                 if (formatContext->classification)              mmfile_free(formatContext->classification);
136                 if (formatContext->year)                                mmfile_free(formatContext->year);
137                 if (formatContext->recDate)                     mmfile_free(formatContext->recDate);
138                 if (formatContext->tagTrackNum)         mmfile_free(formatContext->tagTrackNum);
139                 if (formatContext->rating)                              mmfile_free(formatContext->rating);
140                 if (formatContext->artworkMime)         mmfile_free(formatContext->artworkMime);
141                 if (formatContext->artwork)                     mmfile_free(formatContext->artwork);
142                 if (formatContext->conductor)                   mmfile_free(formatContext->conductor);
143                 if (formatContext->unsyncLyrics)                mmfile_free(formatContext->unsyncLyrics);
144                 if (formatContext->rotate)                              mmfile_free(formatContext->rotate);
145                 if (formatContext->stereoMode)                  mmfile_free(formatContext->stereoMode);
146                 if (formatContext->stitchingSoftware)   mmfile_free(formatContext->stitchingSoftware);
147                 if (formatContext->projectionType)              mmfile_free(formatContext->projectionType);
148                 if (formatContext->metadataSourceV2)    mmfile_free(formatContext->metadataSourceV2);
149
150                 if (clean_all)  /*syncLyrics has to be freed in mm_file_destroy_tag_attrs() except abnormal status */
151                         if (formatContext->syncLyrics)                  mm_file_free_synclyrics_list(formatContext->syncLyrics);
152
153                 if (formatContext->privateFormatData)   mmfile_free(formatContext->privateFormatData);
154                 if (formatContext->privateCodecData)    mmfile_free(formatContext->privateCodecData);
155
156                 if (formatContext->nbStreams > 0) {
157                         int i = 0;
158
159                         /*formatContext->streams[0] is video, formatContext->streams[1] is audio.*/
160                         if (formatContext->streams[0]) mmfile_free(formatContext->streams[0]);
161                         if (formatContext->streams[1]) mmfile_free(formatContext->streams[1]);
162
163                         for (i = 2; (i < formatContext->nbStreams) && (i < MAXSTREAMS); i++) {
164                                 if (formatContext->streams[i]) mmfile_free(formatContext->streams[i]);
165                         }
166                 }
167
168                 if (formatContext->thumbNail) {
169                         if (formatContext->thumbNail->frameData)
170                                 mmfile_free(formatContext->thumbNail->frameData);
171
172                         if (formatContext->thumbNail->configData)
173                                 mmfile_free(formatContext->thumbNail->configData);
174
175                         mmfile_free(formatContext->thumbNail);
176                 }
177
178                 formatContext->videoTotalTrackNum = 0;
179                 formatContext->audioTotalTrackNum = 0;
180                 formatContext->nbStreams = 0;
181         }
182
183         return MMFILE_FORMAT_SUCCESS;
184 }
185
186 int fileExtToFormatType(unsigned long long fileExt)
187 {
188         switch (fileExt) {
189         case MMFILE_EXT_MP4:
190         case MMFILE_EXT_MPEG4:
191         case MMFILE_EXT_M4A:
192         case MMFILE_EXT_MPG:
193         case MMFILE_EXT_MPG4:
194         case MMFILE_EXT_M4V:
195         case MMFILE_EXT_TTS:
196         case MMFILE_EXT_TRP:
197         case MMFILE_EXT_3M:
198         case MMFILE_EXT_26L:
199         case MMFILE_EXT_264:
200                 return MM_FILE_FORMAT_MP4;
201
202         case MMFILE_EXT_3GP:
203                 return MM_FILE_FORMAT_3GP;
204
205         case MMFILE_EXT_AMR:
206         case MMFILE_EXT_AWB:
207                 return MM_FILE_FORMAT_AMR;
208
209         case MMFILE_EXT_WAV:
210                 return MM_FILE_FORMAT_WAV;
211
212         case MMFILE_EXT_MID:
213         case MMFILE_EXT_MIDI:
214         case MMFILE_EXT_SPM:
215                 return MM_FILE_FORMAT_MID;
216
217         case MMFILE_EXT_MP3:
218                 return MM_FILE_FORMAT_MP3;
219
220         case MMFILE_EXT_AAC:
221                 return MM_FILE_FORMAT_AAC;
222
223         case MMFILE_EXT_XMF:
224         case MMFILE_EXT_MXMF:
225                 return MM_FILE_FORMAT_MID;
226
227         case MMFILE_EXT_MMF:
228         case MMFILE_EXT_MA2:
229                 return MM_FILE_FORMAT_MMF;
230
231         case MMFILE_EXT_IMY:
232                 return MM_FILE_FORMAT_IMELODY;
233
234         case MMFILE_EXT_AVI:
235                 return MM_FILE_FORMAT_AVI;
236
237         case MMFILE_EXT_DIVX:
238                 return MM_FILE_FORMAT_DIVX;
239
240         case MMFILE_EXT_ASF:
241         case MMFILE_EXT_ASX:
242                 return MM_FILE_FORMAT_ASF;
243
244         case MMFILE_EXT_WMA:
245                 return MM_FILE_FORMAT_WMA;
246
247         case MMFILE_EXT_WMV:
248                 return MM_FILE_FORMAT_WMV;
249
250         case MMFILE_EXT_OGG:
251                 return MM_FILE_FORMAT_OGG;
252
253         case MMFILE_EXT_MKV:
254         case MMFILE_EXT_MKA:
255         case MMFILE_EXT_WEBM:
256                 return MM_FILE_FORMAT_MATROSKA;
257
258         case MMFILE_EXT_MOV:
259                 return MM_FILE_FORMAT_QT;
260
261         case MMFILE_EXT_FLAC:
262                 return MM_FILE_FORMAT_FLAC;
263
264         case MMFILE_EXT_FLV:
265                 return MM_FILE_FORMAT_FLV;
266
267         case MMFILE_EXT_RM:
268         case MMFILE_EXT_RMVB:
269                 return MM_FILE_FORMAT_REAL;
270
271         case MMFILE_EXT_M2TS:
272         case MMFILE_EXT_MTS:
273         case MMFILE_EXT_TP:
274         case MMFILE_EXT_TS:
275                 return MM_FILE_FORMAT_M2TS;
276
277         case MMFILE_EXT_MPEG:
278                 return MM_FILE_FORMAT_M2PS;
279
280         case MMFILE_EXT_AIF:
281         case MMFILE_EXT_AIFF:
282                 return MM_FILE_FORMAT_AIFF;
283
284         default:
285                 return MM_FILE_FORMAT_NUM;
286         }
287 }
288
289 static int
290 _PreprocessFile(MMFileSourceType *fileSrc, char **urifilename, int *formatEnum)
291 {
292         const char      *fileName = NULL;
293         int                     filename_len = 0;
294         int                     index = 0, skip_index = 0;
295         int ret = 0;
296         MMFileIOHandle *fp = NULL;
297
298         if (fileSrc->type == MM_FILE_SRC_TYPE_FILE) {
299                 unsigned long long fileExt = 0;
300 #ifdef __MMFILE_MMAP_MODE__
301                 const char *uriStr = MMFILE_MMAP_URI;
302 #else
303                 const char *uriStr = MMFILE_FILE_URI;
304 #endif
305                 int uriLen = strlen(uriStr);
306
307                 fileName = (const char *)(fileSrc->file.path);
308                 filename_len = strlen(fileName);
309
310                 int pos = filename_len;
311
312                 *urifilename = mmfile_malloc(uriLen + filename_len + 1);
313                 if (!*urifilename) {
314                         debug_error(DEBUG, "error: mmfile_malloc uriname\n");
315                         goto FILE_FORMAT_FAIL;
316                 }
317
318                 memset(*urifilename, 0x00, uriLen + filename_len + 1);
319                 SAFE_STRLCPY(*urifilename, uriStr, uriLen + filename_len + 1);
320                 SAFE_STRLCAT(*urifilename, fileName, uriLen + filename_len + 1);
321
322                 /**
323                  * Get file extension from file's name
324                  */
325                 while (pos > 0) {
326                         pos--;
327                         if (fileName[pos] == '.')
328                                 break;
329                         fileExt |= (fileName[pos] >= 'A' && fileName[pos] <= 'Z' ? fileName[pos] + 0x20 : fileName[pos]) << (filename_len - pos - 1) * 8;
330                 }
331
332                 skip_index = fileExtToFormatType(fileExt);
333
334                 ret = mmfile_open(&fp, *urifilename, MMFILE_RDONLY);
335
336                 if (ret == MMFILE_IO_FAILED) {
337                         debug_error(DEBUG, "error: mmfile_open\n");
338                         goto FILE_FORMAT_FAIL;
339                 }
340         } else if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) {
341                 char tempURIBuffer[MMFILE_URI_MAX_LEN] = {0, };
342
343                 snprintf(tempURIBuffer, MMFILE_URI_MAX_LEN, "%s%lu:%u", MMFILE_MEM_URI, (unsigned long)fileSrc->memory.ptr, fileSrc->memory.size);
344                 *urifilename = mmfile_strdup(tempURIBuffer);
345                 if (!*urifilename) {
346                         debug_error(DEBUG, "error: uri is NULL\n");
347                         goto FILE_FORMAT_FAIL;
348                 }
349
350                 ret = mmfile_open(&fp, *urifilename, MMFILE_RDONLY);
351
352                 if (ret == MMFILE_IO_FAILED) {
353                         debug_error(DEBUG, "error: mmfile_open\n");
354                         goto FILE_FORMAT_FAIL;
355                 }
356
357                 debug_msg(RELEASE, "uri: %s\n", *urifilename);
358
359                 skip_index = fileSrc->memory.format;
360         } else {
361                 debug_error(DEBUG, "error: invaild input type[memory|file]\n");
362                 goto FILE_FORMAT_FAIL;
363         }
364
365         if (MMFileFunc[skip_index].Valid != NULL && MMFileFunc[skip_index].Valid(fp, NULL, 5)) {        // 3rd argument only mp3
366                 *formatEnum = skip_index;
367                 goto FILE_FORMAT_SUCCESS;
368         } else {
369                 if (skip_index == MM_FILE_FORMAT_M2PS) {
370                         if (MMFileFunc[MM_FILE_FORMAT_M1VIDEO].Valid(fp, NULL, 5)) {
371                                 *formatEnum = MM_FILE_FORMAT_M1VIDEO;
372                                 goto FILE_FORMAT_SUCCESS;
373                         }
374                 }
375                 goto PROBE_PROPER_FILE_TYPE;
376         }
377
378 PROBE_PROPER_FILE_TYPE:
379         for (index = 0; index < MM_FILE_FORMAT_NUM; index++) {
380                 if (index == skip_index)
381                         continue;
382
383                 debug_msg(RELEASE, "search index = [%d]\n", index);
384
385                 switch (index) {
386                 case MM_FILE_FORMAT_QT:
387                 case MM_FILE_FORMAT_3GP:
388                 case MM_FILE_FORMAT_MP4:
389                         *formatEnum = (skip_index == MM_FILE_FORMAT_QT || skip_index == MM_FILE_FORMAT_3GP || skip_index == MM_FILE_FORMAT_MP4) ? MM_FILE_FORMAT_NUM : MM_FILE_FORMAT_3GP;
390                         break;
391
392                 case MM_FILE_FORMAT_ASF:
393                 case MM_FILE_FORMAT_WMA:
394                 case MM_FILE_FORMAT_WMV:
395                         *formatEnum = (skip_index == MM_FILE_FORMAT_ASF || skip_index == MM_FILE_FORMAT_WMA || skip_index == MM_FILE_FORMAT_WMV) ? MM_FILE_FORMAT_NUM : MM_FILE_FORMAT_ASF;
396                         break;
397
398                 case MM_FILE_FORMAT_DIVX:
399                 case MM_FILE_FORMAT_AVI:
400                         *formatEnum = (skip_index == MM_FILE_FORMAT_DIVX || skip_index == MM_FILE_FORMAT_AVI) ? MM_FILE_FORMAT_NUM : MM_FILE_FORMAT_AVI;
401                         break;
402
403                 /* not supported file */
404                 case MM_FILE_FORMAT_NUT:
405                 case MM_FILE_FORMAT_AU:
406                 case MM_FILE_FORMAT_VOB:
407                 case MM_FILE_FORMAT_JPG:
408                         *formatEnum = MM_FILE_FORMAT_NUM;
409                         break;
410
411                 default:
412                         *formatEnum = index;
413                         //debug_error(RELEASE, "error: invaild format enum[%d]\n", index);
414                         break;
415                 }
416
417                 if (MMFileFunc[*formatEnum].Valid != NULL && MMFileFunc[*formatEnum].Valid(fp, NULL, 50)) {
418                         if (fileSrc->type == MM_FILE_SRC_TYPE_MEMORY) fileSrc->memory.format = *formatEnum;
419                         goto FILE_FORMAT_SUCCESS;
420                 }
421         }
422
423 FILE_FORMAT_FAIL:
424         if (index == MM_FILE_FORMAT_NUM)
425                 debug_error(DEBUG, "Can't probe file type\n");
426
427         *formatEnum = -1;
428
429         if (fp)
430                 mmfile_close(fp);
431
432         return MMFILE_FORMAT_FAIL;
433
434
435 FILE_FORMAT_SUCCESS:
436         if (fp)
437                 mmfile_close(fp);
438
439         return MMFILE_FORMAT_SUCCESS;
440 }
441
442 static int _mmfile_format_close(MMFileFormatContext *formatContext, bool clean_all)
443 {
444         if (NULL == formatContext) {
445                 debug_error(DEBUG, "error: invalid params\n");
446                 return MMFILE_FORMAT_FAIL;
447         }
448
449         if (formatContext->Close) {
450                 formatContext->Close(formatContext);
451                 formatContext->Close = NULL;
452         }
453
454         _CleanupFrameContext(formatContext, clean_all);
455
456         if (formatContext)
457                 mmfile_free(formatContext);
458
459         return MMFILE_FORMAT_SUCCESS;
460 }
461
462
463 EXPORT_API
464 int mmfile_format_open(MMFileFormatContext **formatContext, MMFileSourceType *fileSrc)
465 {
466         int index = 0;
467         int ret = 0;
468         MMFileFormatContext *formatObject = NULL;
469
470         if (NULL == fileSrc) {
471                 debug_error(DEBUG, "error: invalid params\n");
472                 return MMFILE_FORMAT_FAIL;
473         }
474
475         /* create formatContext object */
476         formatObject = mmfile_malloc(sizeof(MMFileFormatContext));
477         if (NULL == formatObject) {
478                 debug_error(DEBUG, "error: mmfile_malloc fail for formatObject\n");
479                 *formatContext = NULL;
480                 return MMFILE_FORMAT_FAIL;
481         }
482
483         memset(formatObject, 0x00, sizeof(MMFileFormatContext));
484
485         mmfile_register_io_all();
486
487         /* parsing file extension */
488         formatObject->filesrc = fileSrc;
489
490         formatObject->pre_checked = 0;  /*not yet format checked.*/
491
492         /**
493          * Format detect and validation check.
494          */
495         ret = _PreprocessFile(fileSrc, &formatObject->uriFileName,  &formatObject->formatType);
496         if (MMFILE_FORMAT_SUCCESS != ret) {
497                 debug_error(DEBUG, "error: _PreprocessFile fail\n");
498                 ret = MMFILE_FORMAT_FAIL;
499                 goto exception;
500         }
501
502         formatObject->pre_checked = 1;  /*already file format checked.*/
503
504         /**
505          * Open format function.
506          */
507         if (NULL == MMFileFunc[formatObject->formatType].Open) {
508                 debug_error(DEBUG, "error: Not implemented \n");
509                 ret = MMFILE_FORMAT_FAIL;
510                 goto find_valid_handler;
511         }
512
513         ret = MMFileFunc[formatObject->formatType].Open(formatObject);
514         if (MMFILE_FORMAT_FAIL == ret) {
515                 debug_error(DEBUG, "error: Try other formats\n");
516                 ret = MMFILE_FORMAT_FAIL;
517 /*              goto find_valid_handler; */
518                 goto exception;
519         }
520
521         *formatContext = formatObject;
522         return MMFILE_FORMAT_SUCCESS;
523
524 find_valid_handler:
525         formatObject->pre_checked = 0;  /*do check file format*/
526
527         for (index = 0; index < MM_FILE_FORMAT_NUM + 1; index++) {
528                 if (NULL == MMFileFunc[index].Open) {
529                         debug_error(DEBUG, "error: Not implemented \n");
530                         ret = MMFILE_FORMAT_FAIL;
531                         continue;
532                 }
533
534                 if (formatObject->formatType == index)
535                         continue;
536
537                 ret = MMFileFunc[index].Open(formatObject);
538                 if (MMFILE_FORMAT_FAIL == ret) {
539 /*                      _CleanupFrameContext(formatObject, true); */
540                         continue;
541                 }
542
543                 break;
544         }
545
546         formatObject->formatType = index;
547
548         if (index == MM_FILE_FORMAT_NUM + 1 && MMFILE_FORMAT_FAIL == ret) {
549                 debug_error(DEBUG, "can't find file format handler\n");
550                 _CleanupFrameContext(formatObject, true);
551                 ret = MMFILE_FORMAT_FAIL;
552                 goto exception;
553         }
554
555         formatObject->formatType = index;
556         *formatContext = formatObject;
557
558         return MMFILE_FORMAT_SUCCESS;
559
560 exception:
561         _mmfile_format_close(formatObject, true);
562         *formatContext = NULL;
563
564         return ret;
565 }
566
567 EXPORT_API
568 int mmfile_format_read_stream(MMFileFormatContext *formatContext)
569 {
570         if (NULL == formatContext || NULL == formatContext->ReadStream) {
571                 debug_error(DEBUG, "error: invalid params\n");
572                 return MMFILE_FORMAT_FAIL;
573         }
574
575         return formatContext->ReadStream(formatContext);
576 }
577
578 EXPORT_API
579 int mmfile_format_read_frame(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
580 {
581         if (NULL == formatContext || NULL == frame || NULL == formatContext->ReadFrame) {
582                 debug_error(DEBUG, "error: invalid params\n");
583                 return MMFILE_FORMAT_FAIL;
584         }
585
586         return formatContext->ReadFrame(formatContext, timestamp, frame);
587 }
588
589 EXPORT_API
590 int mmfile_format_read_tag(MMFileFormatContext *formatContext)
591 {
592         if (NULL == formatContext || NULL == formatContext->ReadTag) {
593                 debug_error(DEBUG, "error: invalid params\n");
594                 return MMFILE_FORMAT_FAIL;
595         }
596
597         return formatContext->ReadTag(formatContext);
598 }
599
600
601 EXPORT_API
602 int mmfile_format_close(MMFileFormatContext *formatContext)
603 {
604         return _mmfile_format_close(formatContext, false);
605 }