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