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