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