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