support some format.
[platform/core/multimedia/libmm-fileinfo.git] / mm_file.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 <stdlib.h>
24 #include <unistd.h>     /*for access*/
25 #include <string.h>     /*for strXXX*/
26 #include <dlfcn.h>
27
28 /* exported MM header files */
29 #include <mm_types.h>
30 #include <mm_error.h>
31 #include <mm_file.h>
32
33 /* internal MM header files */
34 #include <mm_attrs_private.h>
35 #include <mm_debug.h>
36
37 /* internal MM File headers */
38 #include "mm_file_formats.h"
39 #include "mm_file_format_frame.h"
40 #include "mm_file_codecs.h"
41 #include "mm_file_utils.h"
42
43
44 #include <sys/time.h>
45
46 //#define CHECK_TIME
47
48 #ifdef CHECK_TIME
49 int64_t gettime(void)
50 {
51         struct timeval tv;
52         gettimeofday(&tv,NULL);
53         return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
54 }
55 #endif
56
57
58 /**
59  * Defines.
60  */
61
62 #ifndef ARRAY_SIZE
63 #define ARRAY_SIZE(arr)         (sizeof(arr) / sizeof((arr)[0]))
64 #endif
65
66 #define _SEEK_POINT_    3000            /*1000 = 1 seconds*/
67
68 #define MM_FILE_TAG_SYNCLYRICS          "tag-synclyrics"                /**< Synchronized Lyrics Information*/
69
70
71 enum {
72         MM_FILE_TAG,
73         MM_FILE_CONTENTS,
74         MM_FILE_INVALID,
75 };
76
77 enum {
78         MM_FILE_PARSE_TYPE_SIMPLE,              /*parse audio/video track num only*/
79         MM_FILE_PARSE_TYPE_NORMAL,              /*parse infomation without thumbnail*/
80         MM_FILE_PARSE_TYPE_ALL,                 /*parse all infomation*/
81         MM_FILE_PARSE_TYPE_SAFE,                /*parse infomation without both thumbnail and stream full-searching*/
82 };
83
84 typedef struct {
85         int     type;
86         int     audio_track_num;
87         int     video_track_num;
88         bool is_uhqa;
89 } MMFILE_PARSE_INFO;
90
91 typedef struct {
92         void *formatFuncHandle;
93         void *codecFuncHandle;
94 } MMFILE_FUNC_HANDLE;
95
96
97
98 /**
99  * global values.
100  */
101 static mmf_attrs_construct_info_t g_tag_attrs[] = {
102         {(char *)"tag-artist",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
103         {(char *)"tag-title",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
104         {(char *)"tag-album",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
105         {(char *)"tag-album-artist",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
106         {(char *)"tag-genre",                   MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
107         {(char *)"tag-author",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
108         {(char *)"tag-copyright",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
109         {(char *)"tag-date",                    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
110         {(char *)"tag-description",             MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
111         {(char *)"tag-comment",         MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
112         {(char *)"tag-artwork",         MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
113         {(char *)"tag-artwork-size",    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
114         {(char *)"tag-artwork-mime",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
115         {(char *)"tag-track-num",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
116         {(char *)"tag-classification",  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
117         {(char *)"tag-rating",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
118         {(char *)"tag-longitude",               MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
119         {(char *)"tag-latitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
120         {(char *)"tag-altitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
121         {(char *)"tag-conductor",               MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
122         {(char *)"tag-unsynclyrics",    MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
123         {(char *)"tag-synclyrics-num",  MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
124         {(char *)"tag-synclyrics",              MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
125         {(char *)"tag-recdate",         MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
126         {(char *)"tag-rotate",                  MMF_VALUE_TYPE_STRING,  MM_ATTRS_FLAG_RW, (void *)NULL},
127         {(char *)"tag-cdis",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
128         {(char *)"tag-smta",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
129 };
130
131 static mmf_attrs_construct_info_t g_content_attrs[] = {
132         {(char *)"content-duration",                    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
133         {(char *)"content-video-codec",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
134         {(char *)"content-video-bitrate",               MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
135         {(char *)"content-video-fps",                   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
136         {(char *)"content-video-width",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
137         {(char *)"content-video-height",                MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
138         {(char *)"content-video-thumbnail",             MMF_VALUE_TYPE_DATA,    MM_ATTRS_FLAG_RW, (void *)NULL},
139         {(char *)"content-video-track-index",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
140         {(char *)"content-video-track-count",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
141         {(char *)"content-audio-codec",         MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
142         {(char *)"content-audio-bitrate",               MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
143         {(char *)"content-audio-channels",              MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
144         {(char *)"content-audio-samplerate",    MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
145         {(char *)"content-audio-track-index",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
146         {(char *)"content-audio-track-count",   MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
147         {(char *)"content-audio-bitpersample",  MMF_VALUE_TYPE_INT,             MM_ATTRS_FLAG_RW, (void *)0},
148 };
149
150 #ifdef __MMFILE_DYN_LOADING__
151 #define MMFILE_FORMAT_SO_FILE_NAME  "libmmfile_formats.so"
152 #define MMFILE_CODEC_SO_FILE_NAME   "libmmfile_codecs.so"
153
154 int (*mmfile_format_open)                       (MMFileFormatContext **formatContext, MMFileSourceType *fileSrc);
155 int (*mmfile_format_read_stream)        (MMFileFormatContext *formatContext);
156 int (*mmfile_format_read_frame)         (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
157 int (*mmfile_format_read_tag)           (MMFileFormatContext *formatContext);
158 int (*mmfile_format_close)                      (MMFileFormatContext *formatContext);
159 int (*mmfile_codec_open)                                (MMFileCodecContext **codecContext, int codecType, int codecId, MMFileCodecFrame *input);
160 int (*mmfile_codec_decode)                      (MMFileCodecContext *codecContext, MMFileCodecFrame *output);
161 int (*mmfile_codec_close)                       (MMFileCodecContext *codecContext);
162 int (*mmfile_format_get_frame)          (const char* path, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height);
163 int (*mmfile_format_get_frame_from_memory)              (const void *data, unsigned int datasize, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height);
164 #endif
165
166 #ifdef __MMFILE_DYN_LOADING__
167 static int _load_dynamic_functions (MMFILE_FUNC_HANDLE* pHandle)
168 {
169 //      static int dll_func_initialized = 0; //disabled
170
171         int ret = 0;
172
173         /* Get from function argument */
174         void *formatFuncHandle = NULL;
175         void *codecFuncHandle = NULL;   
176
177         /* disabled
178         if (dll_func_initialized) {
179                 return 1;
180         }
181         */
182
183         formatFuncHandle = dlopen (MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
184         if (!formatFuncHandle) {
185                 debug_error ("error: %s\n", dlerror());
186                 ret = 0;
187                 goto exception;
188         }
189
190         mmfile_format_open                      = dlsym (formatFuncHandle, "mmfile_format_open");
191         mmfile_format_read_stream       = dlsym (formatFuncHandle, "mmfile_format_read_stream");
192         mmfile_format_read_frame        = dlsym (formatFuncHandle, "mmfile_format_read_frame");
193         mmfile_format_read_tag          = dlsym (formatFuncHandle, "mmfile_format_read_tag");
194         mmfile_format_close                     = dlsym (formatFuncHandle, "mmfile_format_close");
195
196         if ( !mmfile_format_open ||
197                  !mmfile_format_read_stream ||
198                  !mmfile_format_read_frame ||
199                  !mmfile_format_read_tag ||
200                  !mmfile_format_close) {
201
202                 debug_error ("error: %s\n", dlerror());
203                 ret = 0;
204                 goto exception;
205         }
206
207         /*closed at app termination.*/
208         //dlclose (formatFuncHandle);
209
210         codecFuncHandle = dlopen (MMFILE_CODEC_SO_FILE_NAME, RTLD_LAZY | RTLD_GLOBAL);
211         if (!codecFuncHandle) {
212                 debug_error ("error: %s\n", dlerror());
213                 ret = 0;
214                 goto exception;
215         }
216
217         mmfile_codec_open               = dlsym (codecFuncHandle, "mmfile_codec_open");
218         mmfile_codec_decode     = dlsym (codecFuncHandle, "mmfile_codec_decode");
219         mmfile_codec_close              = dlsym (codecFuncHandle, "mmfile_codec_close");
220
221         if ( !mmfile_codec_open || !mmfile_codec_decode || !mmfile_codec_close) {
222                 debug_error ("error: %s\n", dlerror());
223                 ret = 0;
224                 goto exception;
225         }
226
227         /*closed at app termination.*/
228         //dlclose (codecFuncHandle);
229
230 //      dll_func_initialized = 1; // disabled
231
232         pHandle->codecFuncHandle = codecFuncHandle;
233         pHandle->formatFuncHandle = formatFuncHandle;
234
235         return 1;
236
237 exception:
238         if (formatFuncHandle) dlclose (formatFuncHandle);
239         if (codecFuncHandle)  dlclose (codecFuncHandle);
240
241         return ret;
242 }
243
244 static void _unload_dynamic_functions (MMFILE_FUNC_HANDLE* pHandle)
245 {
246 #ifdef __MMFILE_TEST_MODE__
247         debug_fenter();
248 #endif
249
250         if (pHandle->formatFuncHandle)
251         {
252                 dlclose (pHandle->formatFuncHandle);    
253         }
254         if (pHandle->codecFuncHandle)
255         {
256                 dlclose (pHandle->codecFuncHandle);
257         }
258
259 #ifdef __MMFILE_TEST_MODE__
260         debug_fleave();
261 #endif
262 }
263
264
265 #endif /* __MMFILE_DYN_LOADING__ */
266
267 /**
268  * local functions.
269  */
270 static int
271 _is_file_exist (const char *filename)
272 {
273         int ret = 1;
274         if (filename) {
275                 const char* to_access = (strstr(filename,"file://")!=NULL)? filename+7:filename;
276                 ret = access (to_access, R_OK );
277                 if (ret != 0) {
278                         debug_error  ("file [%s] not found.\n", to_access);
279                 }
280         }
281         return !ret;
282 }
283
284 static int
285 _info_set_attr_media (mmf_attrs_t *attrs, MMFileFormatContext *formatContext)
286 {
287         int ret = 0;
288         MMHandleType hattrs = CAST_MM_HANDLE(attrs);
289
290         if (formatContext->commandType == MM_FILE_TAG) 
291         {
292                 if (formatContext->title)                               mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_TITLE, formatContext->title);
293                 if (formatContext->artist)                              mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ARTIST, formatContext->artist);
294                 if (formatContext->author)                      mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_AUTHOR, formatContext->author);
295                 if (formatContext->composer && formatContext->author == NULL)   
296                                                                                         mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_AUTHOR, formatContext->composer);
297                 if (formatContext->album)                               mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ALBUM, formatContext->album);
298                 if (formatContext->album_artist)                                mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ALBUM_ARTIST, formatContext->album_artist);
299                 if (formatContext->copyright)                   mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_COPYRIGHT, formatContext->copyright);
300                 if (formatContext->description)                 mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_DESCRIPTION, formatContext->description);
301                 if (formatContext->comment)                     mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_COMMENT, formatContext->comment);
302                 if (formatContext->genre)                               mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_GENRE, formatContext->genre);
303                 if (formatContext->classification)              mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_CLASSIFICATION, formatContext->classification);
304                 if (formatContext->year)                                mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_DATE, formatContext->year); 
305                 if (formatContext->tagTrackNum)         mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_TRACK_NUM, formatContext->tagTrackNum); 
306                 if (formatContext->rating)                              mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_RATING, formatContext->rating);
307                 if (formatContext->conductor)           mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_CONDUCTOR, formatContext->conductor);
308                 if (formatContext->recDate)                     mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_RECDATE, formatContext->recDate);
309                 if (formatContext->rotate)                      mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ROTATE, formatContext->rotate);
310                                                                                         mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_LONGITUDE, formatContext->longitude);
311                                                                                         mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_LATIDUE, formatContext->latitude);
312                                                                                         mm_attrs_set_double_by_name(hattrs, MM_FILE_TAG_ALTIDUE, formatContext->altitude); 
313                                                                                         mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_SYNCLYRICS_NUM, formatContext->syncLyricsNum);
314                                                                                         mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_CDIS, formatContext->cdis);
315                                                                                         mm_attrs_set_int_by_name(hattrs, MM_FILE_TAG_SMTA, formatContext->smta);
316
317                 if ((formatContext->syncLyricsNum > 0) && (formatContext->syncLyrics))
318                         mm_attrs_set_data_by_name (hattrs, MM_FILE_TAG_SYNCLYRICS, formatContext->syncLyrics, formatContext->syncLyricsNum);
319
320                 if (formatContext->unsyncLyrics)                mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_UNSYNCLYRICS, formatContext->unsyncLyrics);
321
322                 if (formatContext->artwork && formatContext->artworkSize > 0) {
323                         void *artworkCopy = NULL;
324                         artworkCopy = mmfile_malloc ((formatContext->artworkSize));
325                         if ( NULL != artworkCopy ) {
326                                 memcpy (artworkCopy, formatContext->artwork, formatContext->artworkSize);
327                                 mm_attrs_set_data_by_name (hattrs, MM_FILE_TAG_ARTWORK,artworkCopy, formatContext->artworkSize);
328                                 mm_attrs_set_int_by_name (hattrs, MM_FILE_TAG_ARTWORK_SIZE, formatContext->artworkSize);
329                                 if (formatContext->artworkMime) mm_attrs_set_string_by_name(hattrs, MM_FILE_TAG_ARTWORK_MIME, formatContext->artworkMime);
330                         }
331                 }
332         } 
333         else if (formatContext->commandType == MM_FILE_CONTENTS) 
334         {
335                 /*get duration*/
336                 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_DURATION, formatContext->duration);
337                 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_TRACK_COUNT, formatContext->audioTotalTrackNum);
338                 mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, formatContext->videoTotalTrackNum);
339
340                 if (formatContext->videoTotalTrackNum > 0 &&
341                         formatContext->nbStreams > 0 &&
342                         formatContext->streams[MMFILE_VIDEO_STREAM]) {
343
344                         MMFileFormatStream *videoStream = formatContext->streams[MMFILE_VIDEO_STREAM];
345
346                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_CODEC, videoStream->codecId);
347                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_BITRATE, videoStream->bitRate);
348                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_FPS, videoStream->framePerSec);                 
349                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_WIDTH, videoStream->width);
350                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_HEIGHT, videoStream->height);
351
352                         if (formatContext->thumbNail && formatContext->thumbNail->frameData) {
353                                 void *thumbNailCopy = NULL;
354                                 thumbNailCopy = mmfile_malloc (formatContext->thumbNail->frameSize);
355
356                                 if (NULL != thumbNailCopy) {
357                                         memcpy (thumbNailCopy, formatContext->thumbNail->frameData, formatContext->thumbNail->frameSize);
358                                         mm_attrs_set_data_by_name (hattrs, MM_FILE_CONTENT_VIDEO_THUMBNAIL, thumbNailCopy, formatContext->thumbNail->frameSize);
359                                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_WIDTH, formatContext->thumbNail->frameWidth);
360                                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_VIDEO_HEIGHT, formatContext->thumbNail->frameHeight);
361                                 }
362                         }
363                 }
364
365                 if (formatContext->audioTotalTrackNum > 0 &&
366                         formatContext->nbStreams > 0 &&
367                         formatContext->streams[MMFILE_AUDIO_STREAM]) {
368
369                         MMFileFormatStream *audioStream = formatContext->streams[MMFILE_AUDIO_STREAM];
370
371                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_CODEC, audioStream->codecId);
372                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_CHANNELS, audioStream->nbChannel);
373                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_BITRATE, audioStream->bitRate);
374                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_SAMPLERATE, audioStream->samplePerSec);
375                         mm_attrs_set_int_by_name (hattrs, MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, audioStream->bitPerSample);
376                 }
377         }
378         else
379         {
380                 ret = -1;
381         }
382
383         /*commit attrs*/
384         ret = mmf_attrs_commit ((MMHandleType)hattrs);
385
386         return ret;
387 }
388
389 static int
390 _get_contents_info (mmf_attrs_t *attrs, MMFileSourceType *src, MMFILE_PARSE_INFO *parse)
391 {
392         MMFileFormatContext *formatContext = NULL;
393         MMFileCodecContext  *codecContext = NULL;
394         MMFileFormatFrame    frameContext = {0,};
395         MMFileCodecFrame     codecFrame = {0,};
396         MMFileCodecFrame     decodedFrame = {0,};
397
398         int ret = 0;
399         
400         if (!src || !parse)
401                 return MM_ERROR_FILE_INTERNAL;
402
403         ret = mmfile_format_open (&formatContext, src);
404         if (MMFILE_FORMAT_FAIL == ret || formatContext == NULL) {
405                 debug_error ("error: mmfile_format_open\n");
406                 ret = MM_ERROR_FILE_INTERNAL;
407                 goto exception;
408         }
409
410         if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL) {
411                 if (parse->type == MM_FILE_PARSE_TYPE_SAFE)
412                         formatContext->cdis = 1;
413                 ret = mmfile_format_read_stream (formatContext);
414                 if (MMFILE_FORMAT_FAIL == ret) {
415                         debug_error ("error: mmfile_format_read_stream\n");
416                         ret = MM_ERROR_FILE_INTERNAL;
417                         goto exception;
418                 }
419
420                 parse->audio_track_num = formatContext->audioTotalTrackNum;
421                 parse->video_track_num = formatContext->videoTotalTrackNum;
422
423                 /* check uhqa content*/
424                 if (parse->is_uhqa = formatContext->streams[MMFILE_AUDIO_STREAM] != NULL)
425                         parse->is_uhqa = formatContext->streams[MMFILE_AUDIO_STREAM]->is_uhqa;
426
427                 if (parse->type >= MM_FILE_PARSE_TYPE_ALL) {
428                         if (formatContext->videoTotalTrackNum > 0) {
429
430                                 if (parse->type != MM_FILE_PARSE_TYPE_SAFE) {
431                                         if (formatContext->formatType == MM_FILE_FORMAT_3GP ||formatContext->formatType == MM_FILE_FORMAT_MP4) {
432                                                 MMFileUtilGetMetaDataFromMP4 (formatContext);
433                                         }
434                                 }
435                                 MMFileFormatStream *videoStream = formatContext->streams[MMFILE_VIDEO_STREAM];
436                                 unsigned int timestamp = _SEEK_POINT_;
437
438                                 ret = mmfile_format_read_frame (formatContext, timestamp, &frameContext);
439                                 if (MMFILE_FORMAT_FAIL == ret) {
440                                         debug_error ("error: mmfile_format_read_frame\n");
441                                         ret = MM_ERROR_FILE_INTERNAL;
442                                         goto warning;
443                                 }
444
445                                 if (frameContext.bCompressed) {
446                                         codecFrame.frameDataSize = frameContext.frameSize;
447                                         codecFrame.width = frameContext.frameWidth;
448                                         codecFrame.height = frameContext.frameHeight;
449                                         codecFrame.frameData = frameContext.frameData;
450                                         codecFrame.configLen = frameContext.configLenth;
451                                         codecFrame.configData = frameContext.configData;
452                                         codecFrame.version = videoStream->version;
453
454                                         ret = mmfile_codec_open (&codecContext, MMFILE_VIDEO_DECODE, videoStream->codecId, &codecFrame);
455                                         if (MMFILE_FORMAT_FAIL == ret) {
456                                                 debug_error ("error: mmfile_codec_open\n");
457                                                 ret = MM_ERROR_FILE_INTERNAL;
458                                                 goto warning;
459                                         }
460
461                                         ret = mmfile_codec_decode (codecContext, &decodedFrame);
462                                         if (MMFILE_FORMAT_FAIL == ret) {
463                                                 debug_error ("error: mmfile_codec_decode\n");
464                                                 ret = MM_ERROR_FILE_INTERNAL;
465                                                 goto warning;
466                                         }
467                                         
468                                         /* set video thumbnail */
469                                         formatContext->thumbNail = mmfile_malloc (sizeof(MMFileFormatFrame));
470                                         if (NULL == formatContext->thumbNail) {
471                                                 debug_error ("error: mmfile_malloc\n");
472                                                 ret = MM_ERROR_FILE_INTERNAL;
473                                                 goto warning;
474                                         }
475
476                                         formatContext->thumbNail->frameSize = decodedFrame.frameDataSize;
477                                         formatContext->thumbNail->frameWidth = decodedFrame.width;
478                                         formatContext->thumbNail->frameHeight = decodedFrame.height;
479                                         formatContext->thumbNail->frameData = decodedFrame.frameData;
480                                         formatContext->thumbNail->configLenth = 0;
481                                         formatContext->thumbNail->configData = NULL;
482                                 } else {
483                                         formatContext->thumbNail = mmfile_malloc (sizeof(MMFileFormatFrame));
484                                         if (NULL == formatContext->thumbNail) {
485                                                 debug_error ("error: mmfile_format_read_frame\n");
486                                                 ret = MM_ERROR_FILE_INTERNAL;
487                                                 goto warning;
488                                         }
489
490                                         formatContext->thumbNail->frameSize = frameContext.frameSize;
491                                         formatContext->thumbNail->frameWidth = frameContext.frameWidth;
492                                         formatContext->thumbNail->frameHeight = frameContext.frameHeight;
493                                         formatContext->thumbNail->frameData = frameContext.frameData;
494                                         formatContext->thumbNail->configLenth = 0;
495                                         formatContext->thumbNail->configData = NULL;
496                                 }
497                         }
498                 }
499         } else {
500                 /**
501                  * if MM_FILE_PARSE_TYPE_SIMPLE, just get number of each stream.
502                  */
503                 parse->audio_track_num = formatContext->audioTotalTrackNum;
504                 parse->video_track_num = formatContext->videoTotalTrackNum;
505         }
506
507 #ifdef __MMFILE_TEST_MODE__
508         mmfile_format_print_frame (&frameContext);
509 #endif
510
511         formatContext->commandType = MM_FILE_CONTENTS;
512
513         if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL)
514                 _info_set_attr_media (attrs, formatContext);
515
516         if (frameContext.bCompressed) {
517                 if (frameContext.frameData) mmfile_free (frameContext.frameData); 
518                 if (frameContext.configData) mmfile_free (frameContext.configData);
519
520                 if (decodedFrame.frameData) {
521                         mmfile_free (decodedFrame.frameData);
522                         formatContext->thumbNail->frameData = NULL;
523                 }
524                 if (decodedFrame.configData) {
525                         mmfile_free (decodedFrame.configData);
526                         formatContext->thumbNail->configData = NULL;
527                 }
528         } else {
529                 if (frameContext.frameData) {
530                         mmfile_free (frameContext.frameData); 
531                         formatContext->thumbNail->frameData = NULL;
532                 }
533                 if (frameContext.configData) {
534                         mmfile_free (frameContext.configData);
535                         formatContext->thumbNail->configData = NULL;
536                 }
537         }
538
539         if (formatContext)  { mmfile_format_close (formatContext); }
540         if (codecContext)   { mmfile_codec_close (codecContext); }
541
542         return MM_ERROR_NONE;
543
544 warning:
545         formatContext->commandType = MM_FILE_CONTENTS;
546
547         if (frameContext.bCompressed) {
548                 if (frameContext.frameData)
549                         mmfile_free (frameContext.frameData); 
550
551                 if (frameContext.configData) 
552                         mmfile_free (frameContext.configData);
553
554                 if (decodedFrame.frameData) {
555                         mmfile_free (decodedFrame.frameData);
556                         formatContext->thumbNail->frameData = NULL;
557                 }
558
559                 if (decodedFrame.configData) {
560                         mmfile_free (decodedFrame.configData);
561                         formatContext->thumbNail->configData = NULL;
562                 }
563         } else {
564                 if (frameContext.frameData) {
565                         mmfile_free (frameContext.frameData); 
566                         formatContext->thumbNail->frameData = NULL;
567                 }
568                 
569                 if (frameContext.configData) {
570                         mmfile_free (frameContext.configData);
571                         formatContext->thumbNail->configData = NULL;
572                 }
573         }
574
575         if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL)
576                 _info_set_attr_media (attrs, formatContext);
577
578         if (formatContext)  { mmfile_format_close (formatContext); }
579         if (codecContext)   { mmfile_codec_close (codecContext); }
580         return MM_ERROR_NONE;
581
582
583 exception:
584         if (frameContext.bCompressed) {
585                 if (frameContext.frameData)
586                         mmfile_free (frameContext.frameData); 
587
588                 if (frameContext.configData) 
589                         mmfile_free (frameContext.configData);
590
591                 if (decodedFrame.frameData) {
592                         mmfile_free (decodedFrame.frameData);
593                         formatContext->thumbNail->frameData = NULL;
594                 }
595
596                 if (decodedFrame.configData) {
597                         mmfile_free (decodedFrame.configData);
598                         formatContext->thumbNail->configData = NULL;
599                 }
600         } else {
601                 if (frameContext.frameData) {
602                         mmfile_free (frameContext.frameData); 
603                         formatContext->thumbNail->frameData = NULL;
604                 }
605                 
606                 if (frameContext.configData) {
607                         mmfile_free (frameContext.configData);
608                         formatContext->thumbNail->configData = NULL;
609                 }
610         }
611
612         if (formatContext)  { mmfile_format_close (formatContext); }
613         // if (codecContext)   { mmfile_codec_close (codecContext); }   /*dead code*/
614
615         return ret;
616 }
617
618
619 static int
620 _get_tag_info (mmf_attrs_t *attrs, MMFileSourceType *src)
621 {
622         MMFileFormatContext *formatContext = NULL;
623         int ret = 0;
624
625         ret = mmfile_format_open (&formatContext, src);
626         if (MMFILE_FORMAT_FAIL == ret || formatContext == NULL) {
627                 debug_error ("error: mmfile_format_open\n");
628                 ret = MM_ERROR_FILE_INTERNAL;
629                 goto exception;
630         }
631
632         ret = mmfile_format_read_tag (formatContext);
633         if (MMFILE_FORMAT_FAIL == ret) {
634                 debug_warning ("reading tag is fail\n");
635                 ret = MM_ERROR_FILE_INTERNAL;
636                 goto exception;
637         }
638
639         formatContext->commandType = MM_FILE_TAG;
640
641         _info_set_attr_media (attrs, formatContext);
642
643         if (formatContext)  { mmfile_format_close (formatContext); }
644
645         return MM_ERROR_NONE;
646
647
648 exception:
649         if (formatContext)  { mmfile_format_close (formatContext); }
650
651         return MM_ERROR_FILE_INTERNAL;
652 }
653
654
655 /**
656  * global functions.
657  */
658 int mm_file_get_attrs(MMHandleType attrs, char **err_attr_name, const char *first_attribute_name, ...)
659 {
660         int ret = MM_ERROR_NONE;
661         va_list var_args;
662
663         if ( !attrs )   
664         {
665                 debug_error ("Invalid arguments [attrs 0]\n");
666                 return MM_ERROR_INVALID_ARGUMENT;
667         }
668         
669         if ( first_attribute_name == NULL)      
670         {
671                 debug_error ("Invalid arguments [first_attribute_name null]\n");
672                 return MM_ERROR_INVALID_ARGUMENT;
673         }
674
675         /* get requested attributes */
676         va_start (var_args, first_attribute_name);
677         ret = mm_attrs_get_valist(attrs, err_attr_name, first_attribute_name, var_args);
678         va_end (var_args);
679
680         if (ret != MM_ERROR_NONE)
681         {
682                 if (err_attr_name)
683                 {
684                         debug_error ("failed to get %s\n", *err_attr_name);
685                 }
686         }
687
688         return ret;
689 }
690
691 int mm_file_get_synclyrics_info(MMHandleType tag_attrs, int index, unsigned long *time_info, char **lyrics)
692 {
693         int ret = MM_ERROR_NONE;
694         AvSynclyricsInfo* sync_lyric_item = NULL;
695         GList *synclyrics_list = NULL;
696
697 #ifdef __MMFILE_TEST_MODE__
698         debug_fenter();
699 #endif
700
701         if ( (mmf_attrs_t*)tag_attrs == NULL) {
702                 debug_error ("invalid handle");
703                 return MM_ERROR_INVALID_ARGUMENT;
704         }
705
706         ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_SYNCLYRICS, (void **)&synclyrics_list);
707         if(ret != MM_ERROR_NONE) {
708                 #ifdef __MMFILE_TEST_MODE__
709                         debug_warning (  "get data fail");
710                 #endif
711                 return ret;
712         }
713         
714         if(synclyrics_list != NULL) {
715
716                 sync_lyric_item = (AvSynclyricsInfo*)g_list_nth_data(synclyrics_list, index);
717
718                 if(sync_lyric_item == NULL) {
719                 #ifdef __MMFILE_TEST_MODE__
720                                 debug_warning (  "synclyric item is NULL");
721                 #endif
722                         return MM_ERROR_COMMON_ATTR_NOT_EXIST;
723                 }
724
725                 *time_info = sync_lyric_item->time_info;
726                 *lyrics = sync_lyric_item->lyric_info;
727
728         } else {
729                 #ifdef __MMFILE_TEST_MODE__
730                         debug_warning (  "synclyrics_list is NULL");
731                 #endif
732                 return MM_ERROR_COMMON_ATTR_NOT_EXIST;
733         }
734
735         return ret;
736
737 }
738
739 int mm_file_create_tag_attrs(MMHandleType *tag_attrs, const char *filename)
740 {
741         int ret = MM_ERROR_NONE;
742         mmf_attrs_t *attrs = NULL;
743         MMFileSourceType src;
744
745 #ifdef __MMFILE_TEST_MODE__
746         debug_fenter();
747 #endif
748
749         /* Check argument here */
750         if (tag_attrs == NULL) {
751                 debug_error ("Invalid arguments [tag null]\n");
752                 return MM_ERROR_INVALID_ARGUMENT;
753         }
754         if (filename == NULL) {
755                 debug_error ("Invalid arguments [filename null]\n");
756                 return MM_ERROR_INVALID_ARGUMENT;
757         }
758         if ( strlen (filename) == 0)    {
759                 debug_error ("Invalid arguments [filename size 0]\n");
760                 return MM_ERROR_INVALID_ARGUMENT;
761         }
762
763
764 #ifdef __MMFILE_DYN_LOADING__
765         MMFILE_FUNC_HANDLE func_handle;
766         
767         ret = _load_dynamic_functions (&func_handle);
768         if (ret == 0) {
769                 debug_error ("load library error\n");
770                 return MM_ERROR_FILE_INTERNAL;
771         }
772 #endif
773
774         /*set source file infomation*/
775         MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
776
777         ret = _is_file_exist (filename);
778         if (!ret) {
779                 ret = MM_ERROR_FILE_NOT_FOUND;
780                 goto END;
781         }
782
783         /*set attrs*/
784         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("tag", g_tag_attrs, ARRAY_SIZE (g_tag_attrs), NULL, NULL);
785         if (!attrs) {
786                 debug_error ("attribute internal error.\n");
787                 ret = MM_ERROR_FILE_INTERNAL;
788                 goto END;
789         }
790
791         ret = _get_tag_info (attrs, &src);
792         if (ret != MM_ERROR_NONE) {
793                 mmf_attrs_free ((MMHandleType)attrs);
794                 attrs = NULL;
795                 debug_error ("failed to get tag: %s\n", filename);
796         }
797
798         *tag_attrs = (MMHandleType)attrs;
799
800 END:
801 #ifdef __MMFILE_DYN_LOADING__
802         _unload_dynamic_functions (&func_handle);
803 #endif
804
805 #ifdef __MMFILE_TEST_MODE__
806         debug_fleave();
807 #endif
808
809         return ret;
810 }
811
812
813 EXPORT_API
814 int mm_file_destroy_tag_attrs(MMHandleType tag_attrs)
815 {
816         void *artwork = NULL;
817         GList *synclyrics_list = NULL;
818         int ret = MM_ERROR_NONE;
819
820 #ifdef __MMFILE_TEST_MODE__
821         debug_fenter();
822 #endif
823
824         if ( (mmf_attrs_t*)tag_attrs == NULL) {
825                 debug_error ("invalid handle.\n");
826                 return MM_ERROR_INVALID_ARGUMENT;
827         }
828
829         ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_ARTWORK, &artwork);
830
831         if (artwork != NULL) {
832                 mmfile_free (artwork);
833         }
834
835         ret = mm_attrs_get_data_by_name (tag_attrs, MM_FILE_TAG_SYNCLYRICS, (void **)&synclyrics_list);
836
837         if(synclyrics_list != NULL) {
838                 mm_file_free_synclyrics_list(synclyrics_list);
839         }
840
841         mmf_attrs_free (tag_attrs);
842
843 #ifdef __MMFILE_TEST_MODE__
844         debug_fleave();
845 #endif
846
847         return ret;
848 }
849
850 EXPORT_API
851 int mm_file_create_content_attrs (MMHandleType *contents_attrs, const char *filename)
852 {
853         mmf_attrs_t *attrs = NULL;
854         MMFileSourceType src = {0,};
855         MMFILE_PARSE_INFO parse = {0,};
856         int ret = 0;
857
858 #ifdef __MMFILE_TEST_MODE__
859         debug_fenter();
860 #endif
861
862         /* Check argument here */
863         if (contents_attrs == NULL) {
864                 debug_error ("Invalid arguments [contents null]\n");
865                 return MM_ERROR_INVALID_ARGUMENT;
866         }
867         if (filename == NULL) {
868                 debug_error ("Invalid arguments [filename null]\n");
869                 return MM_ERROR_INVALID_ARGUMENT;
870         }
871         if ( strlen (filename) == 0)    {
872                 debug_error ("Invalid arguments [filename size 0]\n");
873                 return MM_ERROR_INVALID_ARGUMENT;
874         }
875
876
877 #ifdef __MMFILE_DYN_LOADING__
878         MMFILE_FUNC_HANDLE func_handle;
879
880         #ifdef CHECK_TIME
881          int64_t ti;
882         ti = gettime();
883         #endif
884
885         ret = _load_dynamic_functions (&func_handle);
886         if (ret == 0) {
887                 debug_error ("load library error\n");
888                 return MM_ERROR_FILE_INTERNAL;
889         }
890
891         #ifdef CHECK_TIME
892         debug_msg("_load_dynamic_functions() = %lld\n", gettime() - ti);
893        #endif
894
895 #endif
896
897         /*set source file infomation*/
898         MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
899
900         ret = _is_file_exist (filename);
901         if (!ret) {
902                 ret = MM_ERROR_FILE_NOT_FOUND;
903                 goto END;
904         }
905
906         /*set attrs*/
907         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
908         if (!attrs) {
909                 debug_error ("attribute internal error.\n");
910                 ret = MM_ERROR_FILE_INTERNAL;
911                 goto END;
912         }
913
914
915         parse.type = MM_FILE_PARSE_TYPE_ALL;
916         ret = _get_contents_info (attrs, &src, &parse);
917         if (ret != MM_ERROR_NONE) {
918                 mmf_attrs_free ((MMHandleType)attrs);
919                 attrs = NULL;
920                 debug_error ("failed to get contents: %s\n", filename);
921         }
922
923         *contents_attrs = (MMHandleType) attrs;
924
925
926 END:
927 #ifdef __MMFILE_DYN_LOADING__
928
929         #ifdef CHECK_TIME
930         ti = gettime();
931         #endif
932
933         _unload_dynamic_functions (&func_handle);
934
935         #ifdef CHECK_TIME
936         debug_msg("_unload_dynamic_functions() = %lld\n", gettime() - ti);
937         #endif
938
939 #endif
940
941 #ifdef __MMFILE_TEST_MODE__
942         debug_fleave();
943 #endif
944
945         return ret;
946 }
947
948
949 EXPORT_API
950 int mm_file_create_tag_attrs_from_memory (MMHandleType *tag_attrs, const void *data, unsigned int size, int format)
951 {
952         mmf_attrs_t *attrs = NULL;
953         MMFileSourceType src;
954         MMFILE_PARSE_INFO parse = {0,};
955         int ret = 0;
956
957 #ifdef __MMFILE_TEST_MODE__
958         debug_fenter();
959 #endif
960
961         /* Check argument here */
962         if (tag_attrs == NULL || data == NULL) {
963                 debug_error ("Invalid arguments\n");
964                 return MM_ERROR_INVALID_ARGUMENT;
965         }
966
967 #ifdef __MMFILE_DYN_LOADING__
968         MMFILE_FUNC_HANDLE func_handle;
969
970         ret = _load_dynamic_functions (&func_handle);
971         if (ret == 0) {
972                 debug_error ("load library error\n");
973                 return MM_ERROR_FILE_INTERNAL;
974         }
975 #endif
976
977         MM_FILE_SET_MEDIA_MEM_SRC (src, data, size, format);
978
979         /*set attrs*/
980         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("tag", g_tag_attrs, ARRAY_SIZE (g_tag_attrs), NULL, NULL);
981         if (!attrs) {
982                 debug_error ("attribute internal error.\n");
983                 ret = MM_ERROR_FILE_INTERNAL;
984                 goto END;
985         }
986
987         parse.type = MM_FILE_PARSE_TYPE_ALL;
988         ret = _get_tag_info (attrs, &src);
989         if (ret != MM_ERROR_NONE) {
990                 mmf_attrs_free ((MMHandleType)attrs);
991                 attrs = NULL;
992                 debug_error ("failed to get tag");
993         }
994
995         *tag_attrs = (MMHandleType)attrs;
996
997 END:
998 #ifdef __MMFILE_DYN_LOADING__
999         _unload_dynamic_functions (&func_handle);
1000 #endif
1001
1002 #ifdef __MMFILE_TEST_MODE__
1003         debug_fleave();
1004 #endif
1005
1006         return ret;
1007 }
1008
1009
1010 EXPORT_API
1011 int mm_file_create_content_attrs_from_memory (MMHandleType *contents_attrs, const void *data, unsigned int size, int format)
1012 {
1013         mmf_attrs_t *attrs = NULL;
1014         MMFileSourceType src;
1015         MMFILE_PARSE_INFO parse = {0,};
1016         int ret = 0;
1017
1018 #ifdef __MMFILE_TEST_MODE__
1019         debug_fenter();
1020 #endif
1021
1022         /* Check argument here */
1023         if (contents_attrs == NULL || data == NULL) {
1024                 debug_error ("Invalid arguments\n");
1025                 return MM_ERROR_INVALID_ARGUMENT;
1026         }
1027
1028 #ifdef __MMFILE_DYN_LOADING__
1029         MMFILE_FUNC_HANDLE func_handle;
1030
1031         ret = _load_dynamic_functions (&func_handle);
1032         if (ret == 0) {
1033                 debug_error ("load library error\n");
1034                 return MM_ERROR_FILE_INTERNAL;
1035         }
1036 #endif
1037
1038         MM_FILE_SET_MEDIA_MEM_SRC (src, data, size, format);
1039
1040         /*set attrs*/
1041         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
1042         if (!attrs) {
1043                 debug_error ("attribute internal error.\n");
1044                 ret = MM_ERROR_FILE_INTERNAL;
1045                 goto END;
1046         }
1047
1048         parse.type = MM_FILE_PARSE_TYPE_ALL;
1049         ret = _get_contents_info (attrs, &src, &parse);
1050         if (ret != MM_ERROR_NONE) {
1051                 mmf_attrs_free ((MMHandleType)attrs);
1052                 attrs = NULL;
1053                 debug_error ("failed to get contents");
1054         }
1055
1056         *contents_attrs = (MMHandleType)attrs;
1057
1058 END:
1059 #ifdef __MMFILE_DYN_LOADING__
1060         _unload_dynamic_functions (&func_handle);
1061 #endif
1062
1063 #ifdef __MMFILE_TEST_MODE__
1064         debug_fleave();
1065 #endif
1066
1067         return ret;
1068 }
1069
1070
1071 EXPORT_API
1072 int mm_file_destroy_content_attrs (MMHandleType contents_attrs)
1073 {
1074         void *thumbnail = NULL;
1075         int ret = MM_ERROR_NONE;
1076
1077 #ifdef __MMFILE_TEST_MODE__
1078         debug_fenter();
1079 #endif
1080
1081         if ((mmf_attrs_t*)contents_attrs == NULL) {
1082                 debug_error ("invalid handle.\n");
1083                 return MM_ERROR_INVALID_ARGUMENT;
1084         }
1085
1086         ret = mm_attrs_get_data_by_name(contents_attrs, MM_FILE_CONTENT_VIDEO_THUMBNAIL, &thumbnail);
1087         if (thumbnail != NULL) {
1088                 mmfile_free (thumbnail);
1089         }
1090
1091         mmf_attrs_free (contents_attrs);
1092
1093 #ifdef __MMFILE_TEST_MODE__
1094         debug_fleave();
1095 #endif
1096
1097         return ret;
1098 }
1099
1100
1101 EXPORT_API
1102 int mm_file_get_stream_info(const char* filename, int *audio_stream_num, int *video_stream_num)
1103 {
1104         MMFileSourceType     src = {0,};
1105         MMFILE_PARSE_INFO    parse = {0,};
1106
1107         int ret = 0;
1108
1109 #ifdef __MMFILE_TEST_MODE__
1110         debug_fenter();
1111 #endif
1112
1113         if (filename == NULL || strlen (filename) == 0 || audio_stream_num == NULL || video_stream_num == NULL) {
1114                 debug_error ("Invalid arguments\n");
1115                 return MM_ERROR_INVALID_ARGUMENT;
1116         }
1117
1118 #ifdef __MMFILE_DYN_LOADING__
1119         MMFILE_FUNC_HANDLE func_handle;
1120
1121         ret = _load_dynamic_functions (&func_handle);
1122         if (ret == 0) {
1123                 debug_error ("load library error\n");
1124                 return MM_ERROR_FILE_INTERNAL;
1125         }
1126 #endif
1127
1128         /*set source file infomation*/
1129         MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
1130
1131         ret = _is_file_exist (filename);
1132         if (!ret) {
1133                 ret = MM_ERROR_FILE_NOT_FOUND;
1134                 goto END;
1135         }
1136
1137         parse.type = MM_FILE_PARSE_TYPE_SIMPLE;
1138         ret = _get_contents_info (NULL, &src, &parse);
1139         if (ret != MM_ERROR_NONE) {
1140                 debug_error ("failed to get stream info: %s\n", filename);
1141         } else {
1142                 if(parse.audio_track_num == 0 && parse.video_track_num == 0) {
1143                         debug_error ("empty header. retry to get stream info: %s\n", filename);
1144                         parse.type = MM_FILE_PARSE_TYPE_NORMAL;
1145                         ret = _get_contents_info (NULL, &src, &parse);
1146                 }
1147         }
1148
1149         /*set number of each stream*/
1150         *audio_stream_num = parse.audio_track_num;
1151         *video_stream_num = parse.video_track_num;
1152
1153 END:
1154 #ifdef __MMFILE_DYN_LOADING__
1155         _unload_dynamic_functions (&func_handle);
1156 #endif
1157
1158 #ifdef __MMFILE_TEST_MODE__
1159         debug_fleave();
1160 #endif
1161
1162         return ret;
1163 }
1164
1165 EXPORT_API
1166 int mm_file_create_content_attrs_simple(MMHandleType *contents_attrs, const char *filename)
1167 {
1168         mmf_attrs_t *attrs = NULL;
1169         MMFileSourceType src = {0,};
1170         MMFILE_PARSE_INFO parse = {0,};
1171         int ret = 0;
1172
1173 #ifdef __MMFILE_TEST_MODE__
1174         debug_fenter();
1175 #endif
1176
1177 #ifdef __MMFILE_DYN_LOADING__
1178         MMFILE_FUNC_HANDLE func_handle;
1179
1180         ret = _load_dynamic_functions (&func_handle);
1181         if (ret == 0) {
1182                 debug_error ("load library error\n");
1183                 return MM_ERROR_FILE_INTERNAL;
1184         }
1185 #endif
1186         if (filename == NULL) {
1187                 ret =  MM_ERROR_INVALID_ARGUMENT;
1188                 goto END;
1189         } else {
1190                 if (strlen (filename) == 0) {
1191                         ret =  MM_ERROR_INVALID_ARGUMENT;
1192                         goto END;
1193                 }
1194         }
1195
1196         /*set source file infomation*/
1197         MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
1198
1199         ret = _is_file_exist (filename);
1200         if (!ret) {
1201                 ret = MM_ERROR_FILE_NOT_FOUND;
1202                 goto END;
1203         }
1204
1205         /*set attrs*/
1206         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
1207         if (!attrs) {
1208                 debug_error ("attribute internal error.\n");
1209                 ret = MM_ERROR_FILE_INTERNAL;
1210                 goto END;
1211         }
1212
1213         parse.type = MM_FILE_PARSE_TYPE_NORMAL;
1214         ret = _get_contents_info (attrs, &src, &parse);
1215         if (ret != MM_ERROR_NONE) {
1216                 mmf_attrs_free ((MMHandleType)attrs);
1217                 attrs = NULL;
1218                 debug_error ("failed to get contents: %s\n", filename);
1219         }
1220
1221         *contents_attrs = (MMHandleType) attrs;
1222
1223 END:
1224 #ifdef __MMFILE_DYN_LOADING__
1225         _unload_dynamic_functions (&func_handle);
1226 #endif
1227
1228 #ifdef __MMFILE_TEST_MODE__
1229         debug_fleave();
1230 #endif
1231
1232         return ret;
1233 }
1234
1235 EXPORT_API
1236 int mm_file_create_content_attrs_safe(MMHandleType *contents_attrs, const char *filename)
1237 {
1238         mmf_attrs_t *attrs = NULL;
1239         MMFileSourceType src = {0,};
1240         MMFILE_PARSE_INFO parse = {0,};
1241         int ret = 0;
1242
1243 #ifdef __MMFILE_TEST_MODE__
1244         debug_fenter();
1245 #endif
1246
1247 #ifdef __MMFILE_DYN_LOADING__
1248         MMFILE_FUNC_HANDLE func_handle;
1249
1250         ret = _load_dynamic_functions (&func_handle);
1251         if (ret == 0) {
1252                 debug_error ("load library error\n");
1253                 return MM_ERROR_FILE_INTERNAL;
1254         }
1255 #endif
1256         if (filename == NULL) {
1257                 ret = MM_ERROR_INVALID_ARGUMENT;
1258                 goto END;
1259         } else {
1260                 if (strlen (filename) == 0) {
1261                         ret = MM_ERROR_INVALID_ARGUMENT;
1262                         goto END;
1263                 }
1264         }
1265
1266         /*set source file infomation*/
1267         MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
1268
1269         ret = _is_file_exist (filename);
1270         if (!ret) {
1271                 ret = MM_ERROR_FILE_NOT_FOUND;
1272                 goto END;
1273         }
1274
1275         /*set attrs*/
1276         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
1277         if (!attrs) {
1278                 debug_error ("attribute internal error.\n");
1279                 ret = MM_ERROR_FILE_INTERNAL;
1280                 goto END;
1281         }
1282
1283         parse.type = MM_FILE_PARSE_TYPE_SAFE;
1284         ret = _get_contents_info (attrs, &src, &parse);
1285         if (ret != MM_ERROR_NONE) {
1286                 mmf_attrs_free ((MMHandleType)attrs);
1287                 attrs = NULL;
1288                 debug_error ("failed to get contents: %s\n", filename);
1289         }
1290
1291         *contents_attrs = (MMHandleType) attrs;
1292
1293 END:
1294 #ifdef __MMFILE_DYN_LOADING__
1295         _unload_dynamic_functions (&func_handle);
1296 #endif
1297
1298 #ifdef __MMFILE_TEST_MODE__
1299         debug_fleave();
1300 #endif
1301
1302         return ret;
1303 }
1304
1305 EXPORT_API
1306 int mm_file_get_video_frame(const char* path, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height)
1307 {
1308         int ret = 0;
1309         void *formatFuncHandle = NULL;
1310
1311         if (path == NULL) {
1312                 debug_error ("Invalid arguments [Path is Null]\n");
1313                 return MM_ERROR_INVALID_ARGUMENT;
1314         }
1315
1316 #ifdef __MMFILE_DYN_LOADING__
1317         /* Get from function argument */
1318         formatFuncHandle = dlopen (MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
1319         if (!formatFuncHandle) {
1320                 debug_error ("error : dlopen");
1321                 goto exception;
1322         }
1323
1324         mmfile_format_get_frame = dlsym (formatFuncHandle, "mmfile_format_get_frame");
1325         if ( !mmfile_format_get_frame ) {
1326                 debug_error ("error : load library");
1327                 goto exception;
1328         }
1329 #endif
1330
1331 #ifdef __MMFILE_TEST_MODE__
1332         debug_msg("file path [%s] is_accurate [%d]", path, is_accurate);
1333 #endif
1334
1335         ret = mmfile_format_get_frame(path, timestamp, is_accurate, frame, size, width, height);
1336         if (ret  == MMFILE_FORMAT_FAIL) {
1337                 debug_error ("error : get frame");
1338                 goto exception;
1339         }
1340
1341         if (formatFuncHandle) dlclose (formatFuncHandle);
1342
1343         return MM_ERROR_NONE;
1344
1345 exception:
1346         if (formatFuncHandle) dlclose (formatFuncHandle);
1347
1348         return MM_ERROR_FILE_INTERNAL;
1349 }
1350
1351 EXPORT_API
1352 int mm_file_get_video_frame_from_memory(const void *data, unsigned int datasize,  double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height)
1353 {
1354         int ret = 0;
1355         void *formatFuncHandle = NULL;
1356
1357         if (data == NULL) {
1358                 debug_error ("Invalid arguments [data is Null]\n");
1359                 return MM_ERROR_INVALID_ARGUMENT;
1360         }
1361
1362         if (datasize == 0) {
1363                 debug_error ("Invalid arguments [datasize is zero]\n");
1364                 return MM_ERROR_INVALID_ARGUMENT;
1365         }
1366
1367 #ifdef __MMFILE_DYN_LOADING__
1368         /* Get from function argument */
1369         formatFuncHandle = dlopen (MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
1370         if (!formatFuncHandle) {
1371                 debug_error ("error : dlopen");
1372                 goto exception;
1373         }
1374
1375         mmfile_format_get_frame_from_memory = dlsym (formatFuncHandle, "mmfile_format_get_frame_from_memory");
1376         if ( !mmfile_format_get_frame_from_memory ) {
1377                 debug_error ("error : load library");
1378                 goto exception;
1379         }
1380 #endif
1381
1382 #ifdef __MMFILE_TEST_MODE__
1383         debug_msg("data [%p], data_size[%d], is_accurate [%d]", data, datasize, is_accurate);
1384 #endif
1385
1386         ret = mmfile_format_get_frame_from_memory(data, datasize, timestamp, is_accurate, frame, size, width, height);
1387         if (ret  == MMFILE_FORMAT_FAIL) {
1388                 debug_error ("error : get frame");
1389                 goto exception;
1390         }
1391
1392         if (formatFuncHandle) dlclose (formatFuncHandle);
1393
1394         return MM_ERROR_NONE;
1395
1396 exception:
1397         if (formatFuncHandle) dlclose (formatFuncHandle);
1398
1399         return MM_ERROR_FILE_INTERNAL;
1400 }
1401
1402 EXPORT_API
1403 int mm_file_check_uhqa(const char* filename, bool *is_uhqa)
1404 {
1405         mmf_attrs_t *attrs = NULL;
1406         MMFileSourceType src = {0,};
1407         MMFILE_PARSE_INFO parse = {0,};
1408         int ret = 0;
1409
1410 #ifdef __MMFILE_DYN_LOADING__
1411         MMFILE_FUNC_HANDLE func_handle;
1412
1413         ret = _load_dynamic_functions (&func_handle);
1414         if (ret == 0) {
1415                 debug_error ("load library error\n");
1416                 return MM_ERROR_FILE_INTERNAL;
1417         }
1418 #endif
1419         if (filename == NULL) {
1420                 ret = MM_ERROR_INVALID_ARGUMENT;
1421                 goto END;
1422         } else {
1423                 if (strlen (filename) == 0) {
1424                         ret = MM_ERROR_INVALID_ARGUMENT;
1425                         goto END;
1426                 }
1427         }
1428
1429         /*set source file infomation*/
1430         MM_FILE_SET_MEDIA_FILE_SRC (src, filename);
1431
1432         ret = _is_file_exist (filename);
1433         if (!ret) {
1434                 ret = MM_ERROR_FILE_NOT_FOUND;
1435                 goto END;
1436         }
1437
1438         /*set attrs*/
1439         attrs = (mmf_attrs_t *) mmf_attrs_new_from_data ("content", g_content_attrs, ARRAY_SIZE (g_content_attrs), NULL, NULL);
1440         if (!attrs) {
1441                 debug_error ("attribute internal error.\n");
1442                 ret = MM_ERROR_FILE_INTERNAL;
1443                 goto END;
1444         }
1445
1446         parse.type = MM_FILE_PARSE_TYPE_NORMAL;
1447         ret = _get_contents_info (attrs, &src, &parse);
1448         if (ret == MM_ERROR_NONE) {
1449                 *is_uhqa = parse.is_uhqa;
1450         } else {
1451                 debug_error ("_get_contents_info failed\n");
1452                 *is_uhqa = FALSE;
1453         }
1454
1455         mmf_attrs_free ((MMHandleType)attrs);
1456         attrs = NULL;
1457
1458 END:
1459 #ifdef __MMFILE_DYN_LOADING__
1460         _unload_dynamic_functions (&func_handle);
1461 #endif
1462
1463 #ifdef __MMFILE_TEST_MODE__
1464         debug_fleave();
1465 #endif
1466
1467         return ret;
1468 }