Remove codec related code
[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_utils.h"
37
38
39 #include <sys/time.h>
40
41 /*#define CHECK_TIME */
42
43 #ifdef CHECK_TIME
44 int64_t gettime(void)
45 {
46         struct timeval tv;
47         gettimeofday(&tv, NULL);
48         return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
49 }
50 #endif
51
52
53 /**
54  * Defines.
55  */
56
57 #ifndef ARRAY_SIZE
58 #define ARRAY_SIZE(arr)         (sizeof(arr) / sizeof((arr)[0]))
59 #endif
60
61 #define _SEEK_POINT_    3000            /*1000 = 1 seconds*/
62
63 #define MM_FILE_TAG_SYNCLYRICS  "tag-synclyrics"        /**< Synchronized Lyrics Information*/
64
65
66 enum {
67         MM_FILE_TAG,
68         MM_FILE_CONTENTS,
69         MM_FILE_INVALID,
70 };
71
72 typedef enum {
73         MM_FILE_PARSE_TYPE_SIMPLE,              /*parse audio/video track num only*/
74         MM_FILE_PARSE_TYPE_NORMAL,              /*parse infomation without thumbnail*/
75         MM_FILE_PARSE_TYPE_ALL,                 /*parse all infomation*/
76         MM_FILE_PARSE_TYPE_SAFE,                /*parse infomation without both thumbnail and stream full-searching*/
77 } MMFILE_PARSE_TYPE;
78
79 typedef struct {
80         int     type;
81         int     audio_track_num;
82         int     video_track_num;
83         bool is_uhqa;
84 } MMFILE_PARSE_INFO;
85
86 typedef struct {
87         void *formatFuncHandle;
88 } MMFILE_FUNC_HANDLE;
89
90
91
92 /**
93  * global values.
94  */
95 static MMAttrsConstructInfo g_tag_attrs[] = {
96         {(char *)"tag-artist",                  MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
97         {(char *)"tag-title",                   MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
98         {(char *)"tag-album",                   MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
99         {(char *)"tag-album-artist",    MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
100         {(char *)"tag-genre",                   MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
101         {(char *)"tag-author",                  MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
102         {(char *)"tag-copyright",               MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
103         {(char *)"tag-date",                    MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
104         {(char *)"tag-description",             MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
105         {(char *)"tag-comment",         MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
106         {(char *)"tag-artwork",         MM_ATTRS_TYPE_DATA,     MM_ATTRS_FLAG_RW, (void *)NULL},
107         {(char *)"tag-artwork-size",    MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
108         {(char *)"tag-artwork-mime",    MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
109         {(char *)"tag-track-num",               MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
110         {(char *)"tag-classification",  MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
111         {(char *)"tag-rating",                  MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
112         {(char *)"tag-longitude",               MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
113         {(char *)"tag-latitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
114         {(char *)"tag-altitude",                MM_ATTRS_TYPE_DOUBLE,   MM_ATTRS_FLAG_RW, (void *)0},
115         {(char *)"tag-conductor",               MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
116         {(char *)"tag-unsynclyrics",    MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
117         {(char *)"tag-synclyrics-num",  MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
118         {(char *)"tag-synclyrics",              MM_ATTRS_TYPE_DATA,     MM_ATTRS_FLAG_RW, (void *)NULL},
119         {(char *)"tag-recdate",         MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
120         {(char *)"tag-part-of-set",             MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
121         {(char *)"tag-rotate",                  MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
122         {(char *)"tag-cdis",                    MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
123         {(char *)"tag-smta",                    MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
124         {(char *)"tag-spherical",                                       MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
125         {(char *)"tag-stitched",                                        MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
126         {(char *)"tag-stitching-software",                      MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
127         {(char *)"tag-projection-type",                         MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
128         {(char *)"tag-stereo-mode",                                     MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
129         {(char *)"tag-source-count",                            MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
130         {(char *)"tag-init-view-heading",                       MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
131         {(char *)"tag-init-view-pitch",                         MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
132         {(char *)"tag-init-view-roll",                          MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
133         {(char *)"tag-timestamp",                                       MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
134         {(char *)"tag-full-pano-width",                         MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
135         {(char *)"tag-full-pano-height",                        MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
136         {(char *)"tag-cropped-area-image-width",        MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
137         {(char *)"tag-cropped-area-image-height",       MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
138         {(char *)"tag-cropped-area-left",                       MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
139         {(char *)"tag-cropped-area-top",                        MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
140         {(char *)"tag-ambisonic-type",                          MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
141         {(char *)"tag-ambisonic-format",                        MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
142         {(char *)"tag-ambisonic-order",                         MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
143         {(char *)"stereo-mode-v2",                                              MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
144         {(char *)"metadata-source-v2",                                  MM_ATTRS_TYPE_STRING,   MM_ATTRS_FLAG_RW, (void *)NULL},
145         {(char *)"proj-type-v2",                                                MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
146         {(char *)"pose-yaw-degrees-v2",                                 MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
147         {(char *)"pose-pitch-degrees-v2",                               MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
148         {(char *)"pose-roll-degrees-v2",                                MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
149         {(char *)"cbmp-layout-v2",                                              MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
150         {(char *)"cbmp-padding-v2",                                             MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
151         {(char *)"equi-projection-bounds-top-v2",               MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
152         {(char *)"equi-projection-bounds-bottom-v2",    MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
153         {(char *)"equi-projection-bounds-left-v2",              MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
154         {(char *)"equi-projection-bounds-right-v2",             MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
155 };
156
157 static MMAttrsConstructInfo g_content_attrs[] = {
158         {(char *)"content-duration",                    MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
159         {(char *)"content-video-codec",         MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
160         {(char *)"content-video-format",                MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
161         {(char *)"content-video-bitrate",               MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
162         {(char *)"content-video-fps",                   MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
163         {(char *)"content-video-width",         MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
164         {(char *)"content-video-height",                MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
165         {(char *)"content-video-thumbnail",             MM_ATTRS_TYPE_DATA,     MM_ATTRS_FLAG_RW, (void *)NULL},
166         {(char *)"content-video-track-index",   MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
167         {(char *)"content-video-track-count",   MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
168         {(char *)"content-audio-codec",         MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
169         {(char *)"content-audio-bitrate",               MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
170         {(char *)"content-audio-channels",              MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
171         {(char *)"content-audio-samplerate",    MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
172         {(char *)"content-audio-track-index",   MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
173         {(char *)"content-audio-track-count",   MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
174         {(char *)"content-audio-bitpersample",  MM_ATTRS_TYPE_INT,              MM_ATTRS_FLAG_RW, (void *)0},
175 };
176
177 #ifdef __MMFILE_DYN_LOADING__
178 #define MMFILE_FORMAT_SO_FILE_NAME  LIBDIR"/libmmfile_formats.so"
179
180 static int (*mmfile_format_open)(MMFileFormatContext **formatContext, MMFileSourceType *fileSrc);
181 static int (*mmfile_format_read_stream)(MMFileFormatContext *formatContext);
182 static int (*mmfile_format_read_frame)(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
183 static int (*mmfile_format_read_tag)(MMFileFormatContext *formatContext);
184 static int (*mmfile_format_close)(MMFileFormatContext *formatContext);
185 static int (*mmfile_format_get_frame)(const char *path, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height);
186 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);
187 #endif
188
189 #ifdef __MMFILE_DYN_LOADING__
190 static int _load_dynamic_functions(MMFILE_FUNC_HANDLE *pHandle)
191 {
192         void *formatFuncHandle = NULL;
193
194         formatFuncHandle = dlopen(MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
195         mm_file_retvm_if_fails(DEBUG, formatFuncHandle, FILEINFO_ERROR_FILE_INTERNAL);
196
197         mmfile_format_open                      = dlsym(formatFuncHandle, "mmfile_format_open");
198         mmfile_format_read_stream       = dlsym(formatFuncHandle, "mmfile_format_read_stream");
199         mmfile_format_read_frame        = dlsym(formatFuncHandle, "mmfile_format_read_frame");
200         mmfile_format_read_tag          = dlsym(formatFuncHandle, "mmfile_format_read_tag");
201         mmfile_format_close                     = dlsym(formatFuncHandle, "mmfile_format_close");
202
203         if (!mmfile_format_open ||
204             !mmfile_format_read_stream ||
205             !mmfile_format_read_frame ||
206             !mmfile_format_read_tag ||
207             !mmfile_format_close) {
208
209                 debug_error(DEBUG, "error: %s\n", "format function load error");
210                 goto exception;
211         }
212
213         pHandle->formatFuncHandle = formatFuncHandle;
214
215         return FILEINFO_ERROR_NONE;
216
217 exception:
218         if (formatFuncHandle)
219                 dlclose(formatFuncHandle);
220
221         return FILEINFO_ERROR_FILE_INTERNAL;
222 }
223
224 static void _unload_dynamic_functions(MMFILE_FUNC_HANDLE *pHandle)
225 {
226         debug_fenter(RELEASE);
227
228         if (pHandle->formatFuncHandle)
229                 dlclose(pHandle->formatFuncHandle);
230
231         debug_fleave(RELEASE);
232 }
233
234 #endif /* __MMFILE_DYN_LOADING__ */
235
236 /**
237  * local functions.
238  */
239 static int _is_file_readable(const char *filename)
240 {
241         mm_file_retvm_if_fails(DEBUG, filename, FILEINFO_ERROR_INVALID_ARGUMENT);
242
243         if (access(filename, R_OK) == -1) {
244                 if (errno == EACCES || errno == EPERM) {
245                         debug_error(DEBUG, "Permission denied [%s]", filename);
246                         return FILEINFO_ERROR_PERMISSION_DENIED;
247                 } else {
248                         debug_error(DEBUG, "Not exist file [%s]", filename);
249                         return FILEINFO_ERROR_FILE_NOT_FOUND;
250                 }
251         }
252
253         return FILEINFO_ERROR_NONE;
254 }
255
256 static int _info_set_attr_media(MMHandleType attrs, MMFileFormatContext *formatContext)
257 {
258         int ret = 0;
259
260         if (formatContext->commandType == MM_FILE_TAG) {
261                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_TITLE, formatContext->title);
262                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_ARTIST, formatContext->artist);
263                 if (formatContext->author)
264                         mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_AUTHOR, formatContext->author);
265                 else
266                         mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_AUTHOR, formatContext->composer);
267                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_ALBUM, formatContext->album);
268                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_ALBUM_ARTIST, formatContext->album_artist);
269                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_COPYRIGHT, formatContext->copyright);
270                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_DESCRIPTION, formatContext->description);
271                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_COMMENT, formatContext->comment);
272                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_GENRE, formatContext->genre);
273                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_CLASSIFICATION, formatContext->classification);
274                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_DATE, formatContext->year);
275                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_TRACK_NUM, formatContext->tagTrackNum);
276                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_RATING, formatContext->rating);
277                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_CONDUCTOR, formatContext->conductor);
278                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_RECDATE, formatContext->recDate);
279                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_POS, formatContext->part_of_set);
280
281                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_ROTATE, formatContext->rotate);
282                 mm_attrs_set_double_by_name(attrs, MM_FILE_TAG_LONGITUDE, formatContext->longitude);
283                 mm_attrs_set_double_by_name(attrs, MM_FILE_TAG_LATIDUE, formatContext->latitude);
284                 mm_attrs_set_double_by_name(attrs, MM_FILE_TAG_ALTIDUE, formatContext->altitude);
285                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SYNCLYRICS_NUM, formatContext->syncLyricsNum);
286                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_CDIS, formatContext->cdis);
287                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SMTA, formatContext->smta);
288
289                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL, formatContext->isSpherical);
290                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_STITCHED, formatContext->isStitched);
291                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_SPHERICAL_STITCHING_SOFTWARE, formatContext->stitchingSoftware);
292                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_SPHERICAL_PROJECTION_TYPE, formatContext->projectionType);
293                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_SPHERICAL_STEREO_MODE, formatContext->stereoMode);
294                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_SOURCE_COUNT, formatContext->sourceCount);
295                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_INIT_VIEW_HEADING, formatContext->initViewHeading);
296                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_INIT_VIEW_PITCH, formatContext->initViewPitch);
297                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_INIT_VIEW_ROLL, formatContext->initViewRoll);
298                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_TIMESTAMP, formatContext->timestamp);
299                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_FULL_PANO_WIDTH, formatContext->fullPanoWidth);
300                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_FULL_PANO_HEIGHT, formatContext->fullPanoHeight);
301                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_WIDTH, formatContext->croppedAreaImageWidth);
302                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_HEIGHT, formatContext->croppedAreaImageHeight);
303                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_LEFT, formatContext->croppedAreaLeft);
304                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_TOP, formatContext->croppedAreaTop);
305
306                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_AMBISONIC_TYPE, formatContext->ambisonicType);
307                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_AMBISONIC_FORMAT, formatContext->ambisonicFormat);
308                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_AMBISONIC_ORDER, formatContext->ambisonicOrder);
309
310                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_STEREO_MODE, formatContext->stereoModeV2);
311                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_METADATA_SOURCE, formatContext->metadataSourceV2);
312                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_PROJ_TYPE, formatContext->projTypeV2);
313                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_POSE_YAW, formatContext->poseYawV2);
314                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_POSE_PITCH, formatContext->posePitchV2);
315                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_POSE_ROLL, formatContext->poseRollV2);
316                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_CBMP_LAYOUT, formatContext->cbmpLayoutV2);
317                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_CBMP_PADDING, formatContext->cbmpPaddingV2);
318                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_TOP, formatContext->equiBoundsTopV2);
319                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_BOTTOM, formatContext->equiBoundsBottomV2);
320                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_LEFT, formatContext->equiBoundsLeftV2);
321                 mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_RIGHT, formatContext->equiBoundsRightV2);
322
323                 mm_attrs_set_data_by_name(attrs, MM_FILE_TAG_SYNCLYRICS, formatContext->syncLyrics, formatContext->syncLyricsNum);
324
325                 mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_UNSYNCLYRICS, formatContext->unsyncLyrics);
326
327                 if (formatContext->artwork && formatContext->artworkSize > 0) {
328                         void *artworkCopy = g_memdup(formatContext->artwork, formatContext->artworkSize);
329
330                         mm_attrs_set_data_by_name(attrs, MM_FILE_TAG_ARTWORK, artworkCopy, formatContext->artworkSize);
331                         mm_attrs_set_int_by_name(attrs, MM_FILE_TAG_ARTWORK_SIZE, formatContext->artworkSize);
332                         mm_attrs_set_string_by_name(attrs, MM_FILE_TAG_ARTWORK_MIME, formatContext->artworkMime);
333                 }
334         } else if (formatContext->commandType == MM_FILE_CONTENTS) {
335                 /*get duration*/
336                 mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_DURATION, formatContext->duration);
337                 mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_AUDIO_TRACK_COUNT, formatContext->audioTotalTrackNum);
338                 mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_TRACK_COUNT, formatContext->videoTotalTrackNum);
339
340                 if (formatContext->videoTotalTrackNum > 0 &&
341                     formatContext->nbStreams > 0 &&
342                     formatContext->streams[MMFILE_VIDEO_STREAM]) {
343
344                         MMFileFormatStream *videoStream = formatContext->streams[MMFILE_VIDEO_STREAM];
345
346                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_FORMAT, formatContext->formatType);
347                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_CODEC, videoStream->codecId);
348                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_BITRATE, videoStream->bitRate);
349                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_FPS, videoStream->framePerSec);
350                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_WIDTH, videoStream->width);
351                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_HEIGHT, videoStream->height);
352
353                         if (formatContext->thumbNail && formatContext->thumbNail->frameData) {
354                                 void *thumbNailCopy = NULL;
355                                 thumbNailCopy = g_memdup(formatContext->thumbNail->frameData, formatContext->thumbNail->frameSize);
356
357                                 mm_attrs_set_data_by_name(attrs, MM_FILE_CONTENT_VIDEO_THUMBNAIL, thumbNailCopy, formatContext->thumbNail->frameSize);
358                                 mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_WIDTH, formatContext->thumbNail->frameWidth);
359                                 mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_VIDEO_HEIGHT, formatContext->thumbNail->frameHeight);
360                         }
361                 }
362
363                 if (formatContext->audioTotalTrackNum > 0 &&
364                     formatContext->nbStreams > 0 &&
365                     formatContext->streams[MMFILE_AUDIO_STREAM]) {
366
367                         MMFileFormatStream *audioStream = formatContext->streams[MMFILE_AUDIO_STREAM];
368
369                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_AUDIO_CODEC, audioStream->codecId);
370                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_AUDIO_CHANNELS, audioStream->nbChannel);
371                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_AUDIO_BITRATE, audioStream->bitRate);
372                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_AUDIO_SAMPLERATE, audioStream->samplePerSec);
373                         mm_attrs_set_int_by_name(attrs, MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, audioStream->bitPerSample);
374                 }
375         } else {
376                 ret = -1;
377         }
378
379         /*commit attrs*/
380         mm_attrs_commit_all(attrs);
381
382         return ret;
383 }
384
385 static int
386 __get_contents_thumbnail(MMFileFormatContext *formatContext)
387 {
388         int ret = FILEINFO_ERROR_NONE;
389         MMFileFormatFrame frameContext = {0, };
390         MMFileFormatFrame *thumbnail = NULL;
391
392         mm_file_retvm_if_fails(DEBUG, formatContext, FILEINFO_ERROR_FILE_INTERNAL);
393
394         if (MMFILE_FORMAT_FAIL == mmfile_format_read_frame(formatContext, _SEEK_POINT_, &frameContext)) {
395                 debug_error(DEBUG, "error: mmfile_format_read_frame\n");
396                 ret = FILEINFO_ERROR_FILE_INTERNAL;
397                 goto exception;
398         }
399
400         /* set video thumbnail */
401         thumbnail = g_new0(MMFileFormatFrame, 1);
402
403         thumbnail->frameSize = frameContext.frameSize;
404         thumbnail->frameWidth = frameContext.frameWidth;
405         thumbnail->frameHeight = frameContext.frameHeight;
406         thumbnail->frameData = frameContext.frameData;
407         thumbnail->configLenth = 0;
408         thumbnail->configData = NULL;
409
410 #ifdef __MMFILE_TEST_MODE__
411         mmfile_format_print_frame(thumbnail);
412 #endif
413
414         formatContext->thumbNail = thumbnail;
415
416         /* because #MMFILE_FORMAT_SUCCESS is different with #FILEINFO_ERROR_NONE */
417         return FILEINFO_ERROR_NONE;
418 exception:
419         mmfile_free(thumbnail);
420         mmfile_free(frameContext.frameData);
421         mmfile_free(frameContext.configData);
422
423         return ret;
424 }
425
426 static int
427 _get_contents_info(MMHandleType attrs, MMFileSourceType *src, MMFILE_PARSE_INFO *parse)
428 {
429         MMFileFormatContext *formatContext = NULL;
430         int ret = 0;
431
432         mm_file_retvm_if_fails(DEBUG, src, FILEINFO_ERROR_FILE_INTERNAL);
433         mm_file_retvm_if_fails(DEBUG, parse, FILEINFO_ERROR_FILE_INTERNAL);
434
435         if (MMFILE_FORMAT_FAIL == mmfile_format_open(&formatContext, src) || formatContext == NULL) {
436                 debug_error(DEBUG, "error: mmfile_format_open\n");
437                 ret = FILEINFO_ERROR_FILE_INTERNAL;
438                 goto exception;
439         }
440
441         if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL) {
442                 if (parse->type == MM_FILE_PARSE_TYPE_SAFE)
443                         formatContext->cdis = 1;
444
445                 if (MMFILE_FORMAT_FAIL == mmfile_format_read_stream(formatContext)) {
446                         debug_error(DEBUG, "error: mmfile_format_read_stream\n");
447                         ret = FILEINFO_ERROR_FILE_INTERNAL;
448                         goto exception;
449                 }
450
451                 parse->audio_track_num = formatContext->audioTotalTrackNum;
452                 parse->video_track_num = formatContext->videoTotalTrackNum;
453
454                 /* check uhqa content*/
455                 if (formatContext->streams[MMFILE_AUDIO_STREAM] != NULL)
456                         parse->is_uhqa = formatContext->streams[MMFILE_AUDIO_STREAM]->is_uhqa;
457                 else
458                         parse->is_uhqa = FALSE;
459
460                 if (parse->type >= MM_FILE_PARSE_TYPE_ALL && formatContext->videoTotalTrackNum > 0) {
461 /*why below code needed?
462 This API is for extracting some attributes not metadata(TAG). mm_file_create_content_attrs() use this API.
463 but MMFileUtilGetMetaDataFromMP4() Extract just TAG info. That is needed for mm_file_create_tag_attrs()*/
464 #if 0
465                         if (parse->type != MM_FILE_PARSE_TYPE_SAFE) {
466                                 if (formatContext->formatType == MM_FILE_FORMAT_3GP || formatContext->formatType == MM_FILE_FORMAT_MP4) {
467                                         MMFileUtilGetMetaDataFromMP4(formatContext);
468                                 }
469                         }
470 #endif
471                         ret = __get_contents_thumbnail(formatContext);
472                         if (FILEINFO_ERROR_NONE != ret) {
473                                 debug_error(DEBUG, "error: __get_contents_thumbnail\n");
474                                 ret = FILEINFO_ERROR_NONE;
475                         }
476                 }
477         } else {
478                 /**
479                  * if MM_FILE_PARSE_TYPE_SIMPLE, just get number of each stream.
480                  */
481                 parse->audio_track_num = formatContext->audioTotalTrackNum;
482                 parse->video_track_num = formatContext->videoTotalTrackNum;
483         }
484
485         formatContext->commandType = MM_FILE_CONTENTS;
486
487         if (parse->type >= MM_FILE_PARSE_TYPE_NORMAL)
488                 _info_set_attr_media(attrs, formatContext);
489
490         if (formatContext->thumbNail) {
491                 mmfile_free(formatContext->thumbNail->frameData);
492                 mmfile_free(formatContext->thumbNail->configData);
493                 mmfile_free(formatContext->thumbNail);
494         }
495
496 exception:
497         if (formatContext)
498                 mmfile_format_close(formatContext);
499
500         return ret;
501 }
502
503
504 static int
505 _get_tag_info(MMHandleType attrs, MMFileSourceType *src)
506 {
507         MMFileFormatContext *formatContext = NULL;
508         int ret = 0;
509
510         ret = mmfile_format_open(&formatContext, src);
511         if (MMFILE_FORMAT_FAIL == ret || formatContext == NULL) {
512                 debug_error(DEBUG, "error: mmfile_format_open\n");
513                 ret = FILEINFO_ERROR_FILE_INTERNAL;
514                 goto exception;
515         }
516
517         ret = mmfile_format_read_tag(formatContext);
518         if (MMFILE_FORMAT_FAIL == ret) {
519                 debug_warning(DEBUG, "reading tag is fail\n");
520                 ret = FILEINFO_ERROR_FILE_INTERNAL;
521                 goto exception;
522         }
523
524         formatContext->commandType = MM_FILE_TAG;
525
526         _info_set_attr_media(attrs, formatContext);
527
528         if (formatContext)  {
529                 mmfile_format_close(formatContext);
530         }
531
532         return FILEINFO_ERROR_NONE;
533
534
535 exception:
536         if (formatContext)  {
537                 mmfile_format_close(formatContext);
538         }
539
540         return FILEINFO_ERROR_FILE_INTERNAL;
541 }
542
543
544 /**
545  * global functions.
546  */
547 int mm_file_get_attrs(MMHandleType attrs, const char *first_attribute_name, ...)
548 {
549         int ret = FILEINFO_ERROR_NONE;
550         va_list var_args;
551         char *err_attr_name = NULL;
552
553         mm_file_retvm_if_fails(DEBUG, attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
554         mm_file_retvm_if_fails(DEBUG, first_attribute_name, FILEINFO_ERROR_INVALID_ARGUMENT);
555
556         /* get requested attributes */
557         va_start(var_args, first_attribute_name);
558         ret = mm_attrs_get_valist(attrs, &err_attr_name, first_attribute_name, var_args);
559         va_end(var_args);
560
561         if (ret != FILEINFO_ERROR_NONE) {
562                 if (err_attr_name) {
563                         debug_error(DEBUG, "failed to get %s\n", err_attr_name);
564                         free(err_attr_name);
565                 }
566         }
567
568         return ret;
569 }
570
571 int mm_file_get_synclyrics_info(MMHandleType tag_attrs, int index, unsigned long *time_info, char **lyrics)
572 {
573         int ret = FILEINFO_ERROR_NONE;
574         AvSynclyricsInfo *sync_lyric_item = NULL;
575         GList *synclyrics_list = NULL;
576
577         debug_fenter(RELEASE);
578
579         mm_file_retvm_if_fails(DEBUG, tag_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
580
581         ret = mm_attrs_get_data_by_name(tag_attrs, MM_FILE_TAG_SYNCLYRICS, (void **)&synclyrics_list);
582         if (ret != FILEINFO_ERROR_NONE) {
583                 debug_warning(RELEASE, "get data fail");
584                 return ret;
585         }
586
587         mm_file_retvm_if_fails(RELEASE, synclyrics_list, FILEINFO_ERROR_ATTR_NOT_EXIST);
588
589         sync_lyric_item = (AvSynclyricsInfo *)g_list_nth_data(synclyrics_list, index);
590
591         mm_file_retvm_if_fails(RELEASE, sync_lyric_item, FILEINFO_ERROR_ATTR_NOT_EXIST);
592
593         *time_info = sync_lyric_item->time_info;
594         *lyrics = sync_lyric_item->lyric_info;
595
596         return ret;
597 }
598
599 int mm_file_create_tag_attrs(MMHandleType *tag_attrs, const char *filename)
600 {
601         int ret = FILEINFO_ERROR_NONE;
602         MMHandleType attrs = NULL;
603         MMFileSourceType src;
604
605         debug_fenter(RELEASE);
606
607         mm_file_retvm_if_fails(DEBUG, tag_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
608
609         ret = _is_file_readable(filename);
610         if (ret != FILEINFO_ERROR_NONE)
611                 return ret;
612
613 #ifdef __MMFILE_DYN_LOADING__
614         MMFILE_FUNC_HANDLE func_handle;
615
616         ret = _load_dynamic_functions(&func_handle);
617         if (ret != FILEINFO_ERROR_NONE) {
618                 debug_error(DEBUG, "load library error\n");
619                 return ret;
620         }
621 #endif
622
623         /*set source file infomation*/
624         MM_FILE_SET_MEDIA_FILE_SRC(src, filename);
625
626         /*set attrs*/
627         ret = mm_attrs_new(g_tag_attrs, ARRAY_SIZE(g_tag_attrs), "tag", NULL, NULL, &attrs);
628         if (ret) {
629                 debug_error(DEBUG, "attribute internal error.\n");
630                 ret = FILEINFO_ERROR_FILE_INTERNAL;
631                 goto END;
632         }
633
634         ret = _get_tag_info(attrs, &src);
635         if (ret != FILEINFO_ERROR_NONE) {
636                 mm_attrs_free(attrs);
637                 attrs = NULL;
638                 debug_error(DEBUG, "failed to get tag: %s\n", filename);
639         }
640
641         *tag_attrs = attrs;
642
643 END:
644 #ifdef __MMFILE_DYN_LOADING__
645         _unload_dynamic_functions(&func_handle);
646 #endif
647
648         debug_fleave(RELEASE);
649
650         return ret;
651 }
652
653
654
655 int mm_file_destroy_tag_attrs(MMHandleType tag_attrs)
656 {
657         void *artwork = NULL;
658         GList *synclyrics_list = NULL;
659         int ret = FILEINFO_ERROR_NONE;
660
661         debug_fenter(RELEASE);
662
663         mm_file_retvm_if_fails(DEBUG, tag_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
664
665         ret = mm_attrs_get_data_by_name(tag_attrs, MM_FILE_TAG_ARTWORK, &artwork);
666         mmfile_free(artwork);
667
668         ret = mm_attrs_get_data_by_name(tag_attrs, MM_FILE_TAG_SYNCLYRICS, (void **)&synclyrics_list);
669         mm_file_free_synclyrics_list(synclyrics_list);
670         mm_attrs_free(tag_attrs);
671
672         debug_fleave(RELEASE);
673
674         return ret;
675 }
676
677 static int __create_content_attrs(MMHandleType *contents_attrs, const char *filename, MMFILE_PARSE_TYPE parse_type)
678 {
679         MMHandleType attrs = NULL;
680         MMFileSourceType src = {0, };
681         MMFILE_PARSE_INFO parse = {0, };
682         int ret = 0;
683
684         debug_fenter(RELEASE);
685
686         mm_file_retvm_if_fails(DEBUG, contents_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
687
688         ret = _is_file_readable(filename);
689         if (ret != FILEINFO_ERROR_NONE)
690                 return ret;
691
692 #ifdef __MMFILE_DYN_LOADING__
693         MMFILE_FUNC_HANDLE func_handle;
694
695 #ifdef CHECK_TIME
696         int64_t ti;
697         ti = gettime();
698 #endif
699
700         ret = _load_dynamic_functions(&func_handle);
701         if (ret != FILEINFO_ERROR_NONE) {
702                 debug_error(DEBUG, "load library error\n");
703                 return ret;
704         }
705
706 #ifdef CHECK_TIME
707         debug_msg(DEBUG, "_load_dynamic_functions() = %lld\n", gettime() - ti);
708 #endif
709
710 #endif
711
712         /*set source file infomation*/
713         MM_FILE_SET_MEDIA_FILE_SRC(src, filename);
714
715         /*set attrs*/
716         ret = mm_attrs_new(g_content_attrs, ARRAY_SIZE(g_content_attrs), "content", NULL, NULL, &attrs);
717         if (ret) {
718                 debug_error(DEBUG, "attribute internal error.\n");
719                 ret = FILEINFO_ERROR_FILE_INTERNAL;
720                 goto END;
721         }
722
723
724         parse.type = parse_type;
725         ret = _get_contents_info(attrs, &src, &parse);
726         if (ret != FILEINFO_ERROR_NONE) {
727                 mm_attrs_free(attrs);
728                 attrs = NULL;
729                 debug_error(DEBUG, "failed to get contents: %s\n", filename);
730         }
731
732         *contents_attrs = attrs;
733
734
735 END:
736 #ifdef __MMFILE_DYN_LOADING__
737
738 #ifdef CHECK_TIME
739         ti = gettime();
740 #endif
741
742         _unload_dynamic_functions(&func_handle);
743
744 #ifdef CHECK_TIME
745         debug_msg(DEBUG, "_unload_dynamic_functions() = %lld\n", gettime() - ti);
746 #endif
747
748 #endif
749
750         debug_fleave(RELEASE);
751
752         return ret;
753 }
754
755
756 int mm_file_create_content_attrs(MMHandleType *contents_attrs, const char *filename)
757 {
758         return __create_content_attrs(contents_attrs, filename, MM_FILE_PARSE_TYPE_ALL);
759 }
760
761
762 int mm_file_create_tag_attrs_from_memory(MMHandleType *tag_attrs, const void *data, unsigned int size, int format)
763 {
764         MMHandleType attrs = NULL;
765         MMFileSourceType src;
766         /*MMFILE_PARSE_INFO parse = {0, };*/
767         int ret = 0;
768
769         debug_fenter(RELEASE);
770
771         mm_file_retvm_if_fails(DEBUG, tag_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
772         mm_file_retvm_if_fails(DEBUG, data, FILEINFO_ERROR_INVALID_ARGUMENT);
773
774 #ifdef __MMFILE_DYN_LOADING__
775         MMFILE_FUNC_HANDLE func_handle;
776
777         ret = _load_dynamic_functions(&func_handle);
778         if (ret != FILEINFO_ERROR_NONE) {
779                 debug_error(DEBUG, "load library error\n");
780                 return ret;
781         }
782 #endif
783
784         MM_FILE_SET_MEDIA_MEM_SRC(src, data, size, format);
785
786         /*set attrs*/
787         ret = mm_attrs_new(g_tag_attrs, ARRAY_SIZE(g_tag_attrs), "tag", NULL, NULL, &attrs);
788         if (ret) {
789                 debug_error(DEBUG, "attribute internal error.\n");
790                 ret = FILEINFO_ERROR_FILE_INTERNAL;
791                 goto END;
792         }
793
794         /*parse.type = MM_FILE_PARSE_TYPE_ALL;*/
795         ret = _get_tag_info(attrs, &src);
796         if (ret != FILEINFO_ERROR_NONE) {
797                 mm_attrs_free(attrs);
798                 attrs = NULL;
799                 debug_error(DEBUG, "failed to get tag");
800         }
801
802         *tag_attrs = attrs;
803
804 END:
805 #ifdef __MMFILE_DYN_LOADING__
806         _unload_dynamic_functions(&func_handle);
807 #endif
808
809         debug_fleave(RELEASE);
810
811         return ret;
812 }
813
814
815
816 int mm_file_create_content_attrs_from_memory(MMHandleType *contents_attrs, const void *data, unsigned int size, int format)
817 {
818         MMHandleType attrs = NULL;
819         MMFileSourceType src;
820         MMFILE_PARSE_INFO parse = {0, };
821         int ret = 0;
822
823         debug_fenter(RELEASE);
824
825         mm_file_retvm_if_fails(DEBUG, contents_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
826         mm_file_retvm_if_fails(DEBUG, data, FILEINFO_ERROR_INVALID_ARGUMENT);
827
828 #ifdef __MMFILE_DYN_LOADING__
829         MMFILE_FUNC_HANDLE func_handle;
830
831         ret = _load_dynamic_functions(&func_handle);
832         if (ret != FILEINFO_ERROR_NONE) {
833                 debug_error(DEBUG, "load library error\n");
834                 return ret;
835         }
836 #endif
837
838         MM_FILE_SET_MEDIA_MEM_SRC(src, data, size, format);
839
840         /*set attrs*/
841         ret = mm_attrs_new(g_content_attrs, ARRAY_SIZE(g_content_attrs), "content", NULL, NULL, &attrs);
842         if (ret) {
843                 debug_error(DEBUG, "attribute internal error.\n");
844                 ret = FILEINFO_ERROR_FILE_INTERNAL;
845                 goto END;
846         }
847
848         parse.type = MM_FILE_PARSE_TYPE_ALL;
849         ret = _get_contents_info(attrs, &src, &parse);
850         if (ret != FILEINFO_ERROR_NONE) {
851                 mm_attrs_free(attrs);
852                 attrs = NULL;
853                 debug_error(DEBUG, "failed to get contents");
854         }
855
856         *contents_attrs = attrs;
857
858 END:
859 #ifdef __MMFILE_DYN_LOADING__
860         _unload_dynamic_functions(&func_handle);
861 #endif
862
863         debug_fleave(RELEASE);
864
865         return ret;
866 }
867
868
869
870 int mm_file_destroy_content_attrs(MMHandleType contents_attrs)
871 {
872         void *thumbnail = NULL;
873         int ret = FILEINFO_ERROR_NONE;
874
875         debug_fenter(RELEASE);
876
877         mm_file_retvm_if_fails(DEBUG, contents_attrs, FILEINFO_ERROR_INVALID_ARGUMENT);
878
879         ret = mm_attrs_get_data_by_name(contents_attrs, MM_FILE_CONTENT_VIDEO_THUMBNAIL, &thumbnail);
880         mmfile_free(thumbnail);
881
882         mm_attrs_free(contents_attrs);
883
884         debug_fleave(RELEASE);
885
886         return ret;
887 }
888
889
890
891 int mm_file_get_stream_info(const char *filename, int *audio_stream_num, int *video_stream_num)
892 {
893         MMFileSourceType     src = {0, };
894         MMFILE_PARSE_INFO    parse = {0, };
895
896         int ret = 0;
897
898         debug_fenter(RELEASE);
899
900         mm_file_retvm_if_fails(DEBUG, audio_stream_num, FILEINFO_ERROR_INVALID_ARGUMENT);
901         mm_file_retvm_if_fails(DEBUG, video_stream_num, FILEINFO_ERROR_INVALID_ARGUMENT);
902
903         ret = _is_file_readable(filename);
904         if (ret != FILEINFO_ERROR_NONE)
905                 return ret;
906
907 #ifdef __MMFILE_DYN_LOADING__
908         MMFILE_FUNC_HANDLE func_handle;
909
910         ret = _load_dynamic_functions(&func_handle);
911         if (ret != FILEINFO_ERROR_NONE) {
912                 debug_error(DEBUG, "load library error\n");
913                 return ret;
914         }
915 #endif
916
917         /*set source file infomation*/
918         MM_FILE_SET_MEDIA_FILE_SRC(src, filename);
919
920
921         parse.type = MM_FILE_PARSE_TYPE_SIMPLE;
922         ret = _get_contents_info(NULL, &src, &parse);
923         if (ret != FILEINFO_ERROR_NONE) {
924                 debug_error(DEBUG, "failed to get stream info: %s\n", filename);
925         } else {
926                 if (parse.audio_track_num == 0 && parse.video_track_num == 0) {
927                         debug_error(DEBUG, "empty header. retry to get stream info: %s\n", filename);
928                         parse.type = MM_FILE_PARSE_TYPE_NORMAL;
929                         ret = _get_contents_info(NULL, &src, &parse);
930                 }
931         }
932
933         /*set number of each stream*/
934         *audio_stream_num = parse.audio_track_num;
935         *video_stream_num = parse.video_track_num;
936
937 #ifdef __MMFILE_DYN_LOADING__
938         _unload_dynamic_functions(&func_handle);
939 #endif
940
941         debug_fleave(RELEASE);
942
943         return ret;
944 }
945
946
947 int mm_file_create_content_attrs_simple(MMHandleType *contents_attrs, const char *filename)
948 {
949         return __create_content_attrs(contents_attrs, filename, MM_FILE_PARSE_TYPE_NORMAL);
950 }
951
952
953 int mm_file_create_content_attrs_safe(MMHandleType *contents_attrs, const char *filename)
954 {
955         return __create_content_attrs(contents_attrs, filename, MM_FILE_PARSE_TYPE_SAFE);
956 }
957
958
959 int mm_file_get_video_frame(const char *path, double timestamp, bool is_accurate, unsigned char **frame, int *size, int *width, int *height)
960 {
961         int ret = 0;
962         void *formatFuncHandle = NULL;
963
964         mm_file_retvm_if_fails(DEBUG, path, FILEINFO_ERROR_INVALID_ARGUMENT);
965
966 #ifdef __MMFILE_DYN_LOADING__
967         /* Get from function argument */
968         formatFuncHandle = dlopen(MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
969         if (!formatFuncHandle) {
970                 debug_error(DEBUG, "error : dlopen");
971                 goto exception;
972         }
973
974         mmfile_format_get_frame = dlsym(formatFuncHandle, "mmfile_format_get_frame");
975         if (!mmfile_format_get_frame) {
976                 debug_error(DEBUG, "error : load library");
977                 goto exception;
978         }
979 #endif
980
981         debug_msg(RELEASE, "file path [%s] is_accurate [%d]", path, is_accurate);
982
983         ret = mmfile_format_get_frame(path, timestamp, is_accurate, frame, size, width, height);
984         if (ret  == MMFILE_FORMAT_FAIL) {
985                 debug_error(DEBUG, "error : get frame");
986                 goto exception;
987         }
988
989         if (formatFuncHandle)
990                 dlclose(formatFuncHandle);
991
992         return FILEINFO_ERROR_NONE;
993
994 exception:
995         if (formatFuncHandle)
996                 dlclose(formatFuncHandle);
997
998         return FILEINFO_ERROR_FILE_INTERNAL;
999 }
1000
1001
1002 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)
1003 {
1004         int ret = 0;
1005         void *formatFuncHandle = NULL;
1006
1007         mm_file_retvm_if_fails(DEBUG, data, FILEINFO_ERROR_INVALID_ARGUMENT);
1008         mm_file_retvm_if_fails(DEBUG, datasize != 0, FILEINFO_ERROR_INVALID_ARGUMENT);
1009
1010 #ifdef __MMFILE_DYN_LOADING__
1011         /* Get from function argument */
1012         formatFuncHandle = dlopen(MMFILE_FORMAT_SO_FILE_NAME, RTLD_LAZY);
1013         if (!formatFuncHandle) {
1014                 debug_error(DEBUG, "error : dlopen");
1015                 goto exception;
1016         }
1017
1018         mmfile_format_get_frame_from_memory = dlsym(formatFuncHandle, "mmfile_format_get_frame_from_memory");
1019         if (!mmfile_format_get_frame_from_memory) {
1020                 debug_error(DEBUG, "error : load library");
1021                 goto exception;
1022         }
1023 #endif
1024
1025         debug_msg(RELEASE, "data [%p], data_size[%d], is_accurate [%d]", data, datasize, is_accurate);
1026
1027         ret = mmfile_format_get_frame_from_memory(data, datasize, timestamp, is_accurate, frame, size, width, height);
1028         if (ret  == MMFILE_FORMAT_FAIL) {
1029                 debug_error(DEBUG, "error : get frame");
1030                 goto exception;
1031         }
1032
1033         if (formatFuncHandle)
1034                 dlclose(formatFuncHandle);
1035
1036         return FILEINFO_ERROR_NONE;
1037
1038 exception:
1039         if (formatFuncHandle)
1040                 dlclose(formatFuncHandle);
1041
1042         return FILEINFO_ERROR_FILE_INTERNAL;
1043 }
1044
1045
1046 int mm_file_check_uhqa(const char *filename, bool *is_uhqa)
1047 {
1048         MMHandleType attrs = NULL;
1049         MMFileSourceType src = {0, };
1050         MMFILE_PARSE_INFO parse = {0, };
1051         int ret = 0;
1052
1053         ret = _is_file_readable(filename);
1054         if (ret != FILEINFO_ERROR_NONE)
1055                 return ret;
1056
1057 #ifdef __MMFILE_DYN_LOADING__
1058         MMFILE_FUNC_HANDLE func_handle;
1059
1060         ret = _load_dynamic_functions(&func_handle);
1061         if (ret != FILEINFO_ERROR_NONE) {
1062                 debug_error(DEBUG, "load library error\n");
1063                 return ret;
1064         }
1065 #endif
1066
1067         /*set source file infomation*/
1068         MM_FILE_SET_MEDIA_FILE_SRC(src, filename);
1069
1070         /*set attrs*/
1071         ret = mm_attrs_new(g_content_attrs, ARRAY_SIZE(g_content_attrs), "content", NULL, NULL, &attrs);
1072         if (ret) {
1073                 debug_error(DEBUG, "attribute internal error.\n");
1074                 ret = FILEINFO_ERROR_FILE_INTERNAL;
1075                 goto END;
1076         }
1077
1078         parse.type = MM_FILE_PARSE_TYPE_NORMAL;
1079         ret = _get_contents_info(attrs, &src, &parse);
1080         if (ret == FILEINFO_ERROR_NONE) {
1081                 *is_uhqa = parse.is_uhqa;
1082         } else {
1083                 debug_error(DEBUG, "_get_contents_info failed\n");
1084                 *is_uhqa = FALSE;
1085         }
1086
1087         mm_attrs_free(attrs);
1088
1089 END:
1090 #ifdef __MMFILE_DYN_LOADING__
1091         _unload_dynamic_functions(&func_handle);
1092 #endif
1093
1094         debug_fleave(RELEASE);
1095
1096         return ret;
1097 }