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