METADATA_AUTHOR has been deprecated. METADATA_COMPOSER will replace it
[platform/core/api/metadata-extractor.git] / src / metadata_extractor.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <mm_file.h>
21 #include <metadata_extractor.h>
22 #include <metadata_extractor_private.h>
23
24 #define META_MAX_LEN    256
25
26 typedef enum {
27         METADATA_TYPE_STREAM    = 0,
28         METADATA_TYPE_ATTR,
29         METADATA_TYPE_TAG,
30 } metadata_extractor_type_e;
31
32 static int __metadata_extractor_check_and_extract_meta(metadata_extractor_s *metadata, metadata_extractor_type_e metadata_type);
33 static int __metadata_extractor_get_stream_info(metadata_extractor_s *metadata, const char *path);
34 static int __metadata_extractor_create_content_attrs(metadata_extractor_s *metadata, const char *path);
35 static int __metadata_extractor_create_tag_attr(metadata_extractor_s *metadata, const char *path);
36 static int __metadata_extractor_create_content_attrs_from_buffer(metadata_extractor_s *metadata, const void *buffer, int size);
37 static int __metadata_extractor_create_tag_attrs_from_buffer(metadata_extractor_s *metadata, const void *buffer, int size);
38 static int __metadata_extractor_get_artwork(metadata_extractor_s *metadata, void **artwork, int *artwork_size);
39 static int __metadata_extractor_get_video_thumbnail(metadata_extractor_s *metadata, void **thumbnail, int *thumbnail_len);
40 static int __metadata_extractor_get_audio_track_count(metadata_extractor_s *metadata, int *track_cnt);
41 static int __metadata_extractor_get_video_track_count(metadata_extractor_s *metadata, int *track_cnt);
42 static int __metadata_extractor_destroy_handle(metadata_extractor_s *metadata);
43 static int __metadata_extractor_get_audio_codec(metadata_extractor_s *metadata, char **audio_codec);
44 static int __metadata_extractor_get_video_codec(metadata_extractor_s *metadata, char **video_codec);
45
46 static int __metadata_extractor_check_and_extract_meta(metadata_extractor_s *metadata, metadata_extractor_type_e metadata_type)
47 {
48         int ret = METADATA_EXTRACTOR_ERROR_NONE;
49
50         if ((!metadata) || ((!metadata->path) && (!metadata->buffer))) {
51                 metadata_extractor_error("INVALID_PARAMETER(0x%08x)", METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER);
52                 return METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER;
53         }
54
55         if (metadata_type == METADATA_TYPE_STREAM) {
56                 if ((metadata) && (metadata->attr_h)) {
57                         return ret;
58                 } else {
59                         metadata_extractor_debug("Extract Stream Info");
60                         ret = __metadata_extractor_get_stream_info(metadata, metadata->path);
61                         if (ret != METADATA_EXTRACTOR_ERROR_NONE)
62                                 return ret;
63                 }
64         } else if (metadata_type == METADATA_TYPE_ATTR) {
65                 if ((metadata) && (metadata->attr_h))
66                         return ret;
67                 else {
68                         metadata_extractor_debug("Extract Content attrs");
69                         if (metadata->path != NULL) {
70                                 ret = __metadata_extractor_create_content_attrs(metadata, metadata->path);
71                                 if (ret != METADATA_EXTRACTOR_ERROR_NONE)
72                                         return ret;
73                         } else if (metadata->buffer != NULL) {
74                                 ret = __metadata_extractor_create_content_attrs_from_buffer(metadata, metadata->buffer, metadata->buffer_size);
75                                 if (ret != METADATA_EXTRACTOR_ERROR_NONE)
76                                         return ret;
77                         }
78                 }
79         } else if (metadata_type == METADATA_TYPE_TAG) {
80                 if ((metadata) && (metadata->tag_h))
81                         return ret;
82                 else {
83                         metadata_extractor_debug("Extract Tag attrs");
84                         if (metadata->path != NULL) {
85                                 ret = __metadata_extractor_create_tag_attr(metadata, metadata->path);
86                                 if (ret != METADATA_EXTRACTOR_ERROR_NONE)
87                                         return ret;
88                         } else if (metadata->buffer != NULL) {
89                                 ret = __metadata_extractor_create_tag_attrs_from_buffer(metadata, metadata->buffer, metadata->buffer_size);
90                                 if (ret != METADATA_EXTRACTOR_ERROR_NONE)
91                                         return ret;
92                         }
93                 }
94         } else {
95                 metadata_extractor_error("INVALID_PARAMETER(%d)", metadata_type);
96                 return METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER;
97         }
98
99         return ret;
100 }
101
102 static int __metadata_extractor_get_stream_info(metadata_extractor_s *metadata, const char *path)
103 {
104         int ret = METADATA_EXTRACTOR_ERROR_NONE;
105         int _audio_track_cnt = 0;
106         int _video_track_cnt = 0;
107
108         ret = mm_file_get_stream_info(path, &_audio_track_cnt, &_video_track_cnt);
109
110         if (ret != FILEINFO_ERROR_NONE) {
111                 if (ret == FILEINFO_ERROR_FILE_NOT_FOUND) {
112                         metadata_extractor_error("FILE_NOT_EXISTS(0x%08x)", METADATA_EXTRACTOR_ERROR_FILE_EXISTS);
113                         return METADATA_EXTRACTOR_ERROR_FILE_EXISTS;
114                 } else {
115                         metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
116                         return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
117                 }
118         }
119
120         metadata->audio_track_cnt = _audio_track_cnt;
121         metadata->video_track_cnt = _video_track_cnt;
122
123         return ret;
124 }
125
126 static int __metadata_extractor_create_content_attrs(metadata_extractor_s *metadata, const char *path)
127 {
128         int ret = METADATA_EXTRACTOR_ERROR_NONE;
129         MMHandleType content = 0;
130         char *err_attr_name = NULL;
131
132         int _audio_track_cnt = 0;
133         int _video_track_cnt = 0;
134
135         ret = mm_file_create_content_attrs(&content, path);
136
137         if (ret != FILEINFO_ERROR_NONE) {
138                 if (ret == FILEINFO_ERROR_FILE_NOT_FOUND) {
139                         metadata_extractor_error("FILE_NOT_EXISTS(0x%08x)", METADATA_EXTRACTOR_ERROR_FILE_EXISTS);
140                         return METADATA_EXTRACTOR_ERROR_FILE_EXISTS;
141                 } else {
142                         metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
143                         return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
144                 }
145         }
146
147         ret = mm_file_get_attrs(content, &err_attr_name,
148                                         MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &_video_track_cnt,
149                                         MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &_audio_track_cnt,
150                                         NULL);
151
152         if (ret != FILEINFO_ERROR_NONE) {
153                 metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
154                 SAFE_FREE(err_attr_name);
155                 mm_file_destroy_content_attrs(content);
156                 return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
157         }
158
159         metadata->attr_h = content;
160         metadata->audio_track_cnt = _audio_track_cnt;
161         metadata->video_track_cnt = _video_track_cnt;
162
163         return ret;
164
165 }
166
167
168 static int __metadata_extractor_create_tag_attr(metadata_extractor_s *metadata, const char *path)
169 {
170         int ret = METADATA_EXTRACTOR_ERROR_NONE;
171         MMHandleType tag = 0;
172
173         ret = mm_file_create_tag_attrs(&tag, path);
174
175         if (ret != FILEINFO_ERROR_NONE) {
176                 if (ret == FILEINFO_ERROR_FILE_NOT_FOUND) {
177                         metadata_extractor_error("FILE_NOT_EXISTS(0x%08x)", METADATA_EXTRACTOR_ERROR_FILE_EXISTS);
178                         return METADATA_EXTRACTOR_ERROR_FILE_EXISTS;
179                 } else {
180                         metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
181                         return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
182                 }
183         }
184
185         metadata->tag_h = tag;
186
187         return ret;
188
189 }
190
191 static int __metadata_extractor_create_content_attrs_from_buffer(metadata_extractor_s *metadata, const void *buffer, int size)
192 {
193         int ret = METADATA_EXTRACTOR_ERROR_NONE;
194         MMHandleType content = 0;
195         char *err_attr_name = NULL;
196
197         int _audio_track_cnt = 0;
198         int _video_track_cnt = 0;
199
200         ret = mm_file_create_content_attrs_from_memory(&content, buffer, size, 0);
201
202         if (ret != FILEINFO_ERROR_NONE) {
203                 if (ret == FILEINFO_ERROR_FILE_NOT_FOUND) {
204                         metadata_extractor_error("FILE_NOT_EXISTS(0x%08x)", METADATA_EXTRACTOR_ERROR_FILE_EXISTS);
205                         return METADATA_EXTRACTOR_ERROR_FILE_EXISTS;
206                 } else {
207                         metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
208                         return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
209                 }
210         }
211
212         ret = mm_file_get_attrs(content, &err_attr_name,
213                                         MM_FILE_CONTENT_VIDEO_TRACK_COUNT, &_video_track_cnt,
214                                         MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &_audio_track_cnt,
215                                         NULL);
216
217         if (ret != FILEINFO_ERROR_NONE) {
218                 metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
219                 SAFE_FREE(err_attr_name);
220                 mm_file_destroy_content_attrs(content);
221                 return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
222         }
223
224         metadata->attr_h = content;
225         metadata->audio_track_cnt = _audio_track_cnt;
226         metadata->video_track_cnt = _video_track_cnt;
227
228         return ret;
229
230 }
231
232 static int __metadata_extractor_create_tag_attrs_from_buffer(metadata_extractor_s *metadata, const void *buffer, int size)
233 {
234         int ret = METADATA_EXTRACTOR_ERROR_NONE;
235         MMHandleType tag = 0;
236
237         ret = mm_file_create_tag_attrs_from_memory(&tag, buffer, size, 0);
238
239         if (ret != FILEINFO_ERROR_NONE) {
240                 if (ret == FILEINFO_ERROR_FILE_NOT_FOUND) {
241                         metadata_extractor_error("FILE_NOT_EXISTS(0x%08x)", METADATA_EXTRACTOR_ERROR_FILE_EXISTS);
242                         return METADATA_EXTRACTOR_ERROR_FILE_EXISTS;
243                 } else {
244                         metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED(0x%08x)", ret);
245                         return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
246                 }
247         }
248
249         metadata->tag_h = tag;
250
251         return ret;
252
253 }
254
255 static int __metadata_extractor_get_attr_int(metadata_extractor_s *metadata, const char *attribute_name, int *attr)
256 {
257         int ret = METADATA_EXTRACTOR_ERROR_NONE;
258         char *err_attr_name = NULL;
259         int _attr = 0;
260
261         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
262         metadata_extractor_retvm_if(metadata->attr_h == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Attr handle is null");
263         metadata_extractor_retvm_if(!ME_STRING_VALID(attribute_name), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid attribute_name");
264         metadata_extractor_retvm_if(attr == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "attr is null");
265
266         ret = mm_file_get_attrs(metadata->attr_h, &err_attr_name, attribute_name, &_attr, NULL);
267         metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
268
269         *attr = _attr;
270
271         return ret;
272 }
273
274 static int __metadata_extractor_get_audio_attr_int(metadata_extractor_s *metadata, const char *attribute_name, int *attr)
275 {
276         int ret = METADATA_EXTRACTOR_ERROR_NONE;
277         char *err_attr_name = NULL;
278         int _attr = 0;
279
280         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
281         metadata_extractor_retvm_if(metadata->attr_h == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Attr handle is null");
282         metadata_extractor_retvm_if(!ME_STRING_VALID(attribute_name), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid attribute_name");
283         metadata_extractor_retvm_if(attr == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "attr is null");
284
285         if (metadata->audio_track_cnt > 0) {
286                 ret = mm_file_get_attrs(metadata->attr_h, &err_attr_name, attribute_name, &_attr, NULL);
287                 metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
288         }
289
290         *attr = _attr;
291
292         return ret;
293 }
294
295 static int __metadata_extractor_get_video_attr_int(metadata_extractor_s *metadata, const char *attribute_name, int *attr)
296 {
297         int ret = METADATA_EXTRACTOR_ERROR_NONE;
298         char *err_attr_name = NULL;
299         int _attr = 0;
300
301         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
302         metadata_extractor_retvm_if(metadata->attr_h == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Attr handle is null");
303         metadata_extractor_retvm_if(!ME_STRING_VALID(attribute_name), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid attribute_name");
304         metadata_extractor_retvm_if(attr == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "attr is null");
305
306         if (metadata->video_track_cnt > 0) {
307                 ret = mm_file_get_attrs(metadata->attr_h, &err_attr_name, attribute_name, &_attr, NULL);
308                 metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
309         }
310
311         *attr = _attr;
312
313         return ret;
314 }
315
316 static int __metadata_extractor_get_audio_track_count(metadata_extractor_s *metadata, int *track_cnt)
317 {
318         int ret = METADATA_EXTRACTOR_ERROR_NONE;
319
320         metadata_extractor_retvm_if(!metadata, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
321
322         *track_cnt = metadata->audio_track_cnt;
323
324         return ret;
325 }
326
327 static int __metadata_extractor_get_video_thumbnail(metadata_extractor_s *metadata, void **thumbnail, int *thumbnail_len)
328 {
329         int ret = METADATA_EXTRACTOR_ERROR_NONE;
330         char *err_attr_name = NULL;
331         void *_video_thumbnail = NULL;
332         int _video_thumbnail_len = 0;
333
334         metadata_extractor_retvm_if((!metadata) || (!metadata->attr_h), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
335
336         if (metadata->video_track_cnt > 0) {
337                 ret = mm_file_get_attrs(metadata->attr_h, &err_attr_name, MM_FILE_CONTENT_VIDEO_THUMBNAIL, &_video_thumbnail, &_video_thumbnail_len, NULL);
338                 metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
339         }
340
341         *thumbnail = _video_thumbnail;
342         *thumbnail_len = _video_thumbnail_len;
343
344         return ret;
345 }
346
347 static int __metadata_extractor_get_video_track_count(metadata_extractor_s *metadata, int *track_cnt)
348 {
349         int ret = METADATA_EXTRACTOR_ERROR_NONE;
350
351         metadata_extractor_retvm_if(!metadata, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
352
353         *track_cnt = metadata->video_track_cnt;
354
355         return ret;
356 }
357
358 static int __metadata_extractor_get_tag_str(metadata_extractor_s *metadata, const char *attribute_name, char **tag)
359 {
360         int ret = METADATA_EXTRACTOR_ERROR_NONE;
361         char *err_attr_name = NULL;
362         char *_tag = NULL;
363         int _tag_len = 0;
364
365         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
366         metadata_extractor_retvm_if(metadata->tag_h == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Tag handle is null");
367         metadata_extractor_retvm_if(!ME_STRING_VALID(attribute_name), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid attribute_name");
368         metadata_extractor_retvm_if(tag == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "tag is null");
369
370         ret = mm_file_get_attrs(metadata->tag_h, &err_attr_name, attribute_name, &_tag, &_tag_len, NULL);
371         metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
372
373         *tag = _tag;
374
375         return ret;
376 }
377
378 static int __metadata_extractor_get_tag_int(metadata_extractor_s *metadata, const char *attribute_name, int *tag)
379 {
380         int ret = METADATA_EXTRACTOR_ERROR_NONE;
381         char *err_attr_name = NULL;
382         int _tag = 0;
383
384         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
385         metadata_extractor_retvm_if(metadata->tag_h == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Tag handle is null");
386         metadata_extractor_retvm_if(!ME_STRING_VALID(attribute_name), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid attribute_name");
387         metadata_extractor_retvm_if(tag == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "tag is null");
388
389         ret = mm_file_get_attrs(metadata->tag_h, &err_attr_name, attribute_name, &_tag, NULL);
390         metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
391
392         *tag = _tag;
393
394         return ret;
395 }
396
397 static int __metadata_extractor_get_tag_double(metadata_extractor_s *metadata, const char *attribute_name, double *tag)
398 {
399         int ret = METADATA_EXTRACTOR_ERROR_NONE;
400         char *err_attr_name = NULL;
401         double _tag = 0;
402
403         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
404         metadata_extractor_retvm_if(metadata->tag_h == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Tag handle is null");
405         metadata_extractor_retvm_if(!ME_STRING_VALID(attribute_name), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid attribute_name");
406         metadata_extractor_retvm_if(tag == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "tag is null");
407
408         ret = mm_file_get_attrs(metadata->tag_h, &err_attr_name, attribute_name, &_tag, NULL);
409         metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
410
411         *tag = _tag;
412
413         return ret;
414 }
415
416 static int __metadata_extractor_get_artwork(metadata_extractor_s *metadata, void **artwork, int *artwork_size)
417 {
418         int ret = METADATA_EXTRACTOR_ERROR_NONE;
419         char *err_attr_name = NULL;
420         void *_artwork = NULL;
421         int _artwork_size = 0;
422         int _tag_len = 0;
423
424         ret = mm_file_get_attrs(metadata->tag_h, &err_attr_name, MM_FILE_TAG_ARTWORK_SIZE, &_artwork_size, NULL);
425         metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
426
427         if (_artwork_size > 0) {
428                 ret = mm_file_get_attrs(metadata->tag_h, &err_attr_name, MM_FILE_TAG_ARTWORK, &_artwork, &_tag_len, NULL);
429                 metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, err_attr_name);
430         }
431
432         *artwork = _artwork;
433         *artwork_size = _artwork_size;
434
435         return ret;
436 }
437
438 static int __metadata_extractor_get_audio_codec(metadata_extractor_s *metadata, char **audio_codec)
439 {
440         int ret = METADATA_EXTRACTOR_ERROR_NONE;
441         int audio_codec_idx = 0;
442         int audio_codec_cnt = 45;
443
444         const char *AudioCodecTypeString[] = {
445                 "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW", "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",
446                 "G711", "G722", "G722.1",       "G722.2  (AMR-WB)", "G723 wideband speech", "G726 (ADPCM)", "G728 speech",      "G729", "G729a",        "G729.1",
447                 "Real",
448                 "AAC-Low complexity",   "AAC-Main profile", "AAC-Scalable sample rate", "AAC-Long term prediction", "AAC-High Efficiency v1",   "AAC-High efficiency v2",
449                 "DolbyDigital", "Apple Lossless",       "Sony proprietary", "SPEEX",    "Vorbis",       "AIFF", "AU",   "None (will be deprecated)",
450                 "PCM",  "ALAW", "MULAW",        "MS ADPCM", "FLAC"
451         };
452
453         ret = __metadata_extractor_get_audio_attr_int(metadata, MM_FILE_CONTENT_AUDIO_CODEC, &audio_codec_idx);
454         metadata_extractor_retvm_if(ret != METADATA_EXTRACTOR_ERROR_NONE, ret, "Fail to get codec idx");
455
456         if (audio_codec_idx < audio_codec_cnt)
457                 *audio_codec = strdup(AudioCodecTypeString[audio_codec_idx]);
458         else {
459                 metadata_extractor_error("Invalid Audio Codec [%d]", audio_codec_idx);
460                 *audio_codec = NULL;
461         }
462
463         return ret;
464 }
465
466 static int __metadata_extractor_get_video_codec(metadata_extractor_s *metadata, char **video_codec)
467 {
468         int ret = METADATA_EXTRACTOR_ERROR_NONE;
469         int video_codec_idx = 0;
470         int video_codec_cnt = 29;
471
472         const char *VideoCodecTypeString[] = {
473                 "None (will be deprecated)",
474                 "H263", "H264", "H26L", "MPEG4", "MPEG1", "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2", "H263v2",  "H263v3",
475                 "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",  "MPEG4 part-2 Advanced Simple profile", "MPEG4 part-2 Main profile",
476                 "MPEG4 part-2 Core profile", "MPEG4 part-2 Adv Coding Eff profile", "MPEG4 part-2 Adv RealTime Simple profile",
477                 "MPEG4 part-10 (h.264)",        "Real", "VC-1", "AVS",  "Cinepak",      "Indeo",        "Theora", "Flv"
478         };
479
480         ret = __metadata_extractor_get_video_attr_int(metadata, MM_FILE_CONTENT_AUDIO_CODEC, &video_codec_idx);
481         metadata_extractor_retvm_if(ret != METADATA_EXTRACTOR_ERROR_NONE, ret, "Fail to get codec idx");
482
483         if (video_codec_idx < video_codec_cnt)
484                 *video_codec = strdup(VideoCodecTypeString[video_codec_idx]);
485         else {
486                 metadata_extractor_error("Invalid Video Codec[%d]", video_codec_idx);
487                 *video_codec = NULL;
488         }
489
490         return ret;
491 }
492
493 static int __metadata_extractor_destroy_handle(metadata_extractor_s *metadata)
494 {
495         int ret = METADATA_EXTRACTOR_ERROR_NONE;
496
497         if (metadata->attr_h) {
498                 ret = mm_file_destroy_content_attrs(metadata->attr_h);
499                 metadata_extractor_retvm_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, "Failed to destroy attribute handle");
500         }
501
502         if (metadata->tag_h) {
503                 ret = mm_file_destroy_tag_attrs(metadata->tag_h);
504                 metadata_extractor_retvm_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, "Failed to destroy tag handle");
505         }
506
507         return ret;
508 }
509
510 int metadata_extractor_create(metadata_extractor_h *metadata)
511 {
512         int ret = METADATA_EXTRACTOR_ERROR_NONE;
513
514         metadata_extractor_retvm_if(metadata == NULL, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Handle is null");
515
516         metadata_extractor_s *_metadata = (metadata_extractor_s *)calloc(1, sizeof(metadata_extractor_s));
517         metadata_extractor_retvm_if(_metadata == NULL, METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, "Memory allocation failure");
518
519         _metadata->path = NULL;
520         _metadata->buffer = NULL;
521         _metadata->buffer_size = 0;
522         _metadata->audio_track_cnt = 0;
523         _metadata->video_track_cnt = 0;
524
525         *metadata = (metadata_extractor_h)_metadata;
526
527         return ret;
528 }
529
530 int metadata_extractor_set_path(metadata_extractor_h metadata, const char *path)
531 {
532         int ret = METADATA_EXTRACTOR_ERROR_NONE;
533         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
534
535         metadata_extractor_retvm_if((_metadata == NULL) || (path == NULL), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
536
537         /*check file path.. */
538         if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
539                 metadata_extractor_sucure_info("path[%s] is exists.", path);
540         } else {
541                 metadata_extractor_sucure_info("path[%s] is not exists.", path);
542                 return METADATA_EXTRACTOR_ERROR_FILE_EXISTS;
543         }
544
545         if ((_metadata->path != NULL) || (_metadata->buffer != NULL)) {
546                 __metadata_extractor_destroy_handle(_metadata);
547                 SAFE_FREE(_metadata->path);
548                 _metadata->attr_h = 0;
549                 _metadata->tag_h = 0;
550         }
551
552         _metadata->path = strdup(path);
553         metadata_extractor_retvm_if(_metadata->path == NULL, METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, "Memory allocation failure");
554
555         return ret;
556 }
557
558 int metadata_extractor_set_buffer(metadata_extractor_h metadata, const void *buffer, int size)
559 {
560         int ret = METADATA_EXTRACTOR_ERROR_NONE;
561         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
562
563         metadata_extractor_retvm_if((_metadata == NULL) || (buffer == NULL) || (size <= 0), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
564
565         if ((_metadata->path != NULL) || (_metadata->buffer != NULL)) {
566                 __metadata_extractor_destroy_handle(_metadata);
567                 SAFE_FREE(_metadata->path);
568                 _metadata->attr_h = 0;
569                 _metadata->tag_h = 0;
570         }
571
572         _metadata->buffer = (void *)buffer;
573         _metadata->buffer_size = size;
574
575         return ret;
576 }
577
578 int metadata_extractor_destroy(metadata_extractor_h metadata)
579 {
580         int ret = METADATA_EXTRACTOR_ERROR_NONE;
581         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
582
583         metadata_extractor_retvm_if(!_metadata, METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
584
585         ret = __metadata_extractor_destroy_handle(_metadata);
586
587         SAFE_FREE(_metadata->path);
588         SAFE_FREE(_metadata);
589
590         return ret;
591 }
592
593 int metadata_extractor_get_synclyrics(metadata_extractor_h metadata, int index, unsigned long *time_stamp, char **lyrics)
594 {
595         int ret = METADATA_EXTRACTOR_ERROR_NONE;
596         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
597         unsigned long _time_info = 0;
598         char *_lyrics = NULL;
599         int _synclyrics_num = 0;
600
601         metadata_extractor_retvm_if((!_metadata) || ((!_metadata->path) && (!_metadata->buffer)), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
602
603         ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_TAG);
604         if (ret != METADATA_EXTRACTOR_ERROR_NONE)
605                 return ret;
606
607         ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SYNCLYRICS_NUM, &_synclyrics_num);
608         if (ret != METADATA_EXTRACTOR_ERROR_NONE)
609                 return ret;
610
611         if ((_synclyrics_num > 0) && (index < _synclyrics_num)) {
612                 ret = mm_file_get_synclyrics_info((MMHandleType)_metadata->tag_h, index, &_time_info, &_lyrics);
613                 metadata_extractor_retvm_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, "Internal operation error");
614
615                 if ((_lyrics != NULL) && (strlen(_lyrics) > 0)) {
616                         *lyrics = strdup(_lyrics);
617                         metadata_extractor_retvm_if(*lyrics == NULL, METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, "Memory allocation failure");
618                 } else
619                         *lyrics = NULL;
620
621                 *time_stamp = _time_info;
622         } else {
623                 *lyrics = NULL;
624                 *time_stamp = 0;
625         }
626
627         return ret;
628 }
629
630 int metadata_extractor_get_metadata(metadata_extractor_h metadata, metadata_extractor_attr_e attribute, char **value)
631 {
632         int ret = METADATA_EXTRACTOR_ERROR_NONE;
633         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
634         int i_value = 0;
635         double d_value = 0;
636         char *s_value = NULL;
637         int is_string = 0;
638         int is_double = 0;
639
640         metadata_extractor_retvm_if((!_metadata) || ((!_metadata->path) && (!_metadata->buffer)), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
641
642         if ((attribute == METADATA_HAS_VIDEO) || (attribute == METADATA_HAS_AUDIO)) {
643                 if (_metadata->path != NULL)
644                         ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_STREAM);
645                 else
646                         ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_ATTR);
647         } else if ((attribute >= METADATA_DURATION) && (attribute < METADATA_HAS_AUDIO))
648                 ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_ATTR);
649         else if ((attribute > METADATA_HAS_AUDIO) && (attribute <= METADATA_ROTATE))
650                 ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_TAG);
651 #ifdef SUPPORT_GSPHERICAL_METADATA
652         else if (((attribute >= METADATA_360) && (attribute <= METADATA_AMBISONIC_ORDER)))
653                 ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_TAG);
654 #else
655         else if (attribute == METADATA_360)
656                 ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_TAG);
657 #endif
658         else if ((attribute == METADATA_AUDIO_CODEC) || (attribute == METADATA_VIDEO_CODEC))
659                 ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_ATTR);
660         else {
661                 metadata_extractor_error("INVALID_PARAMETER [%d]", attribute);
662                 ret = METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER;
663         }
664
665         if (ret != METADATA_EXTRACTOR_ERROR_NONE)
666                 return ret;
667
668         /*metadata_extractor_debug("attribute [%d]", attribute); */
669
670         switch ((int)attribute) {  /*TODO (m.alieksieie): Remove casting after ACR*/
671         case METADATA_DURATION: {
672                 is_string = 0;
673                 ret = __metadata_extractor_get_attr_int(_metadata, MM_FILE_CONTENT_DURATION, &i_value);
674                 break;
675         }
676         case METADATA_VIDEO_CODEC: {
677                 is_string = 1;
678                 ret = __metadata_extractor_get_video_codec(_metadata, &s_value);
679                 break;
680         }
681         case METADATA_VIDEO_BITRATE: {
682                 is_string = 0;
683                 ret = __metadata_extractor_get_video_attr_int(_metadata, MM_FILE_CONTENT_VIDEO_BITRATE, &i_value);
684                 break;
685         }
686         case METADATA_VIDEO_FPS: {
687                 is_string = 0;
688                 ret = __metadata_extractor_get_video_attr_int(_metadata, MM_FILE_CONTENT_VIDEO_FPS, &i_value);
689                 break;
690         }
691         case METADATA_VIDEO_WIDTH: {
692                 is_string = 0;
693                 ret = __metadata_extractor_get_video_attr_int(_metadata, MM_FILE_CONTENT_VIDEO_WIDTH, &i_value);
694                 break;
695         }
696         case METADATA_VIDEO_HEIGHT: {
697                 is_string = 0;
698                 ret = __metadata_extractor_get_video_attr_int(_metadata, MM_FILE_CONTENT_VIDEO_HEIGHT, &i_value);
699                 break;
700         }
701         case METADATA_HAS_VIDEO: {
702                 is_string = 0;
703                 ret = __metadata_extractor_get_video_track_count(_metadata, &i_value);
704                 break;
705         }
706         case METADATA_AUDIO_CODEC: {
707                 is_string = 1;
708                 ret = __metadata_extractor_get_audio_codec(_metadata, &s_value);
709                 break;
710         }
711         case METADATA_AUDIO_BITRATE: {
712                 is_string = 0;
713                 ret = __metadata_extractor_get_audio_attr_int(_metadata, MM_FILE_CONTENT_AUDIO_BITRATE, &i_value);
714                 break;
715         }
716         case METADATA_AUDIO_CHANNELS: {
717                 is_string = 0;
718                 ret = __metadata_extractor_get_audio_attr_int(_metadata, MM_FILE_CONTENT_AUDIO_CHANNELS, &i_value);
719                 break;
720         }
721         case METADATA_AUDIO_SAMPLERATE: {
722                 is_string = 0;
723                 ret = __metadata_extractor_get_audio_attr_int(_metadata, MM_FILE_CONTENT_AUDIO_SAMPLERATE, &i_value);
724                 break;
725         }
726         case METADATA_AUDIO_BITPERSAMPLE: {
727                 is_string = 0;
728                 ret = __metadata_extractor_get_audio_attr_int(_metadata, MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, &i_value);
729                 break;
730         }
731         case METADATA_HAS_AUDIO: {
732                 is_string = 0;
733                 ret = __metadata_extractor_get_audio_track_count(_metadata, &i_value);
734                 break;
735         }
736         case METADATA_ARTIST: {
737                 is_string = 1;
738                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_ARTIST, &s_value);
739                 break;
740         }
741         case METADATA_TITLE: {
742                 is_string = 1;
743                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_TITLE, &s_value);
744                 break;
745         }
746         case METADATA_ALBUM: {
747                 is_string = 1;
748                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_ALBUM, &s_value);
749                 break;
750         }
751         case METADATA_ALBUM_ARTIST: {
752                 is_string = 1;
753                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_ALBUM_ARTIST, &s_value);
754                 break;
755         }
756         case METADATA_GENRE: {
757                 is_string = 1;
758                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_GENRE, &s_value);
759                 break;
760         }
761         case METADATA_COMPOSER: {
762                 is_string = 1;
763                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_AUTHOR, &s_value);
764                 break;
765         }
766         case METADATA_COPYRIGHT: {
767                 is_string = 1;
768                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_COPYRIGHT, &s_value);
769                 break;
770         }
771         case METADATA_DATE: {
772                 is_string = 1;
773                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_DATE, &s_value);
774                 break;
775         }
776         case METADATA_DESCRIPTION: {
777                 is_string = 1;
778                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_DESCRIPTION, &s_value);
779                 break;
780         }
781         case METADATA_COMMENT: {
782                 is_string = 1;
783                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_COMMENT, &s_value);
784                 break;
785         }
786         case METADATA_TRACK_NUM: {
787                 is_string = 1;
788                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_TRACK_NUM, &s_value);
789                 break;
790         }
791         case METADATA_CLASSIFICATION: {
792                 is_string = 1;
793                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_CLASSIFICATION, &s_value);
794                 break;
795         }
796         case METADATA_RATING: {
797                 is_string = 1;
798                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_RATING, &s_value);
799                 break;
800         }
801         case METADATA_LONGITUDE: {
802                 is_double = 1;
803                 ret = __metadata_extractor_get_tag_double(_metadata, MM_FILE_TAG_LONGITUDE, &d_value);
804                 break;
805         }
806         case METADATA_LATITUDE: {
807                 is_double = 1;
808                 ret = __metadata_extractor_get_tag_double(_metadata, MM_FILE_TAG_LATIDUE, &d_value);
809                 break;
810         }
811         case METADATA_ALTITUDE: {
812                 is_double = 1;
813                 ret = __metadata_extractor_get_tag_double(_metadata, MM_FILE_TAG_ALTIDUE, &d_value);
814                 break;
815         }
816         case METADATA_CONDUCTOR: {
817                 is_string = 1;
818                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_CONDUCTOR, &s_value);
819                 break;
820         }
821         case METADATA_UNSYNCLYRICS: {
822                 is_string = 1;
823                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_UNSYNCLYRICS, &s_value);
824                 break;
825         }
826         case METADATA_SYNCLYRICS_NUM: {
827                 is_string = 0;
828                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SYNCLYRICS_NUM, &i_value);
829                 break;
830         }
831         case METADATA_RECDATE: {
832                 is_string = 1;
833                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_RECDATE, &s_value);
834                 break;
835         }
836         case METADATA_ROTATE: {
837                 is_string = 1;
838                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_ROTATE, &s_value);
839                 break;
840         }
841         case METADATA_360: {
842                 is_string = 0;
843                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL, &i_value);
844                 break;
845         }
846 #ifdef SUPPORT_GSPHERICAL_METADATA
847         case METADATA_360_V1_STITCHED: {
848                 is_string = 0;
849                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_STITCHED, &i_value);
850                 break;
851         }
852         case METADATA_360_V1_PROJECTION_TYPE: {
853                 is_string = 1;
854                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_SPHERICAL_PROJECTION_TYPE, &s_value);
855                 break;
856         }
857         case METADATA_360_V1_STITCHING_SOFTWARE: {
858                 is_string = 1;
859                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_SPHERICAL_STITCHING_SOFTWARE, &s_value);
860                 break;
861         }
862         case METADATA_360_V1_STEREO_MODE: {
863                 is_string = 1;
864                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_SPHERICAL_STEREO_MODE, &s_value);
865                 break;
866         }
867         case METADATA_360_V1_SOURCE_COUNT: {
868                 is_string = 0;
869                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_SOURCE_COUNT, &i_value);
870                 break;
871         }
872         case METADATA_360_V1_INIT_VIEW_HEADING: {
873                 is_string = 0;
874                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_INIT_VIEW_HEADING, &i_value);
875                 break;
876         }
877         case METADATA_360_V1_INIT_VIEW_PITCH: {
878                 is_string = 0;
879                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_INIT_VIEW_PITCH, &i_value);
880                 break;
881         }
882         case METADATA_360_V1_INIT_VIEW_ROLL: {
883                 is_string = 0;
884                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_INIT_VIEW_ROLL, &i_value);
885                 break;
886         }
887         case METADATA_360_V1_TIMESTAMP: {
888                 is_string = 0;
889                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_TIMESTAMP, &i_value);
890                 break;
891         }
892         case METADATA_360_V1_FULL_PANO_WIDTH: {
893                 is_string = 0;
894                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_FULL_PANO_WIDTH, &i_value);
895                 break;
896         }
897         case METADATA_360_V1_FULL_PANO_HEIGHT: {
898                 is_string = 0;
899                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_FULL_PANO_HEIGHT, &i_value);
900                 break;
901         }
902         case METADATA_360_V1_CROPPED_AREA_IMAGE_WIDTH: {
903                 is_string = 0;
904                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_WIDTH, &i_value);
905                 break;
906         }
907         case METADATA_360_V1_CROPPED_AREA_IMAGE_HEIGHT: {
908                 is_string = 0;
909                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_HEIGHT, &i_value);
910                 break;
911         }
912         case METADATA_360_V1_CROPPED_AREA_LEFT: {
913                 is_string = 0;
914                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_LEFT, &i_value);
915                 break;
916         }
917         case METADATA_360_V1_CROPPED_AREA_TOP: {
918                 is_string = 0;
919                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_CROPPED_AREA_TOP, &i_value);
920                 break;
921         }
922         case METADATA_360_V2_STEREO_MODE: {
923                 is_string = 0;
924                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_STEREO_MODE, &i_value);
925                 break;
926         }
927         case METADATA_360_V2_METADATA_SOURCE: {
928                 is_string = 1;
929                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_SPHERICAL_V2_METADATA_SOURCE, &s_value);
930                 break;
931         }
932         case METADATA_360_V2_PROJ_TYPE: {
933                 is_string = 0;
934                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_PROJ_TYPE, &i_value);
935                 break;
936         }
937         case METADATA_360_V2_POSE_YAW: {
938                 is_string = 0;
939                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_POSE_YAW, &i_value);
940                 break;
941         }
942         case METADATA_360_V2_POSE_PITCH: {
943                 is_string = 0;
944                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_POSE_PITCH, &i_value);
945                 break;
946         }
947         case METADATA_360_V2_POSE_ROLL: {
948                 is_string = 0;
949                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_POSE_ROLL, &i_value);
950                 break;
951         }
952         case METADATA_360_V2_CBMP_LAYOUT: {
953                 is_string = 0;
954                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_CBMP_LAYOUT, &i_value);
955                 break;
956         }
957         case METADATA_360_V2_CBMP_PADDING: {
958                 is_string = 0;
959                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_CBMP_PADDING, &i_value);
960                 break;
961         }
962         case METADATA_360_V2_EQUI_BOUNDS_TOP: {
963                 is_string = 0;
964                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_TOP, &i_value);
965                 break;
966         }
967         case METADATA_360_V2_EQUI_BOUNDS_BOTTOM: {
968                 is_string = 0;
969                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_BOTTOM, &i_value);
970                 break;
971         }
972         case METADATA_360_V2_EQUI_BOUNDS_LEFT: {
973                 is_string = 0;
974                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_LEFT, &i_value);
975                 break;
976         }
977         case METADATA_360_V2_EQUI_BOUNDS_RIGHT: {
978                 is_string = 0;
979                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_RIGHT, &i_value);
980                 break;
981         }
982         case METADATA_AMBISONIC_TYPE: {
983                 is_string = 0;
984                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_AMBISONIC_TYPE, &i_value);
985                 break;
986         }
987         case METADATA_AMBISONIC_FORMAT: {
988                 is_string = 0;
989                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_AMBISONIC_FORMAT, &i_value);
990                 break;
991         }
992         case METADATA_AMBISONIC_ORDER: {
993                 is_string = 0;
994                 ret = __metadata_extractor_get_tag_int(_metadata, MM_FILE_TAG_AMBISONIC_ORDER, &i_value);
995                 break;
996         }
997 #endif
998         default:
999                 break;
1000         }
1001
1002         if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
1003                 *value = NULL;
1004                 return ret;
1005         }
1006
1007         if (is_string) {
1008                 if ((s_value != NULL) && (strlen(s_value) > 0)) {
1009                         *value = strdup(s_value);
1010                         /*Only use strdup in video_codec and audio_codec */
1011                         if (attribute == METADATA_VIDEO_CODEC || attribute == METADATA_AUDIO_CODEC)
1012                                 SAFE_FREE(s_value);
1013
1014                         if (*value == NULL) {
1015                                 metadata_extractor_error("OUT_OF_MEMORY(0x%08x)", METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY);
1016                                 return METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY;
1017                         }
1018                 } else {
1019                         if (attribute == METADATA_VIDEO_CODEC || attribute == METADATA_AUDIO_CODEC)
1020                                 SAFE_FREE(s_value);
1021                         *value = NULL;
1022                 }
1023         } else {
1024                 char extracted_metadata[META_MAX_LEN] = {0, };
1025
1026                 if (is_double)
1027                         snprintf(extracted_metadata, sizeof(extracted_metadata), "%f", d_value);
1028                 else
1029                         snprintf(extracted_metadata, sizeof(extracted_metadata), "%d", i_value);
1030
1031                 *value = strdup(extracted_metadata);
1032                 metadata_extractor_retvm_if(*value == NULL, METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, "Memory allocation failure");
1033         }
1034
1035         return ret;
1036 }
1037
1038 int metadata_extractor_get_artwork(metadata_extractor_h metadata, void **artwork, int *size, char **mime_type)
1039 {
1040         int ret = METADATA_EXTRACTOR_ERROR_NONE;
1041         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
1042         void *_artwork = NULL;
1043         int _artwork_size = 0;
1044         char *_artwork_mime = NULL;
1045
1046         metadata_extractor_retvm_if((!_metadata) || ((!_metadata->path) && (!_metadata->buffer)), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
1047
1048         ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_TAG);
1049         metadata_extractor_retvm_if(ret != METADATA_EXTRACTOR_ERROR_NONE, ret, "Error in __metadata_extractor_check_and_extract_meta()");
1050
1051         ret = __metadata_extractor_get_artwork(_metadata, &_artwork, &_artwork_size);
1052         metadata_extractor_retvm_if(ret != METADATA_EXTRACTOR_ERROR_NONE, ret, "Fail to get artwork");
1053
1054         if ((_artwork_size > 0) && (_artwork != NULL)) {
1055                 ret = __metadata_extractor_get_tag_str(_metadata, MM_FILE_TAG_ARTWORK_MIME, &_artwork_mime);
1056                 if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
1057                         *artwork = NULL;
1058                         *size = 0;
1059
1060                         return ret;
1061                 }
1062
1063                 *artwork = calloc(1, _artwork_size);
1064                 if (*artwork != NULL) {
1065                         memcpy(*artwork, _artwork, _artwork_size);
1066                         *size = _artwork_size;
1067                 } else {
1068                         *size = 0;
1069                 }
1070
1071                 if ((_artwork_mime != NULL) && (strlen(_artwork_mime) > 0)) {
1072                         *mime_type = strdup(_artwork_mime);
1073                         metadata_extractor_retvm_if(*mime_type == NULL, METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, "Memory allocation failure");
1074                 } else {
1075                         *mime_type = NULL;
1076                 }
1077
1078         } else {
1079                 *artwork = NULL;
1080                 *mime_type = NULL;
1081                 *size = 0;
1082         }
1083
1084         return ret;
1085 }
1086
1087 int metadata_extractor_get_frame(metadata_extractor_h metadata, void **frame, int *size)
1088 {
1089         int ret = METADATA_EXTRACTOR_ERROR_NONE;
1090         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
1091         void *_frame = NULL;
1092         int _frame_size = 0;
1093
1094         metadata_extractor_retvm_if((!_metadata) || ((!_metadata->path) && (!_metadata->buffer)) || (!size), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
1095
1096         ret = __metadata_extractor_check_and_extract_meta(_metadata, METADATA_TYPE_ATTR);
1097         if (ret != METADATA_EXTRACTOR_ERROR_NONE)
1098                 return ret;
1099
1100         ret = __metadata_extractor_get_video_thumbnail(_metadata, &_frame, &_frame_size);
1101         if (ret != METADATA_EXTRACTOR_ERROR_NONE)
1102                 return ret;
1103
1104         if ((_frame_size > 0) && (_frame != NULL)) {
1105                 *frame = calloc(1, _frame_size);
1106                 metadata_extractor_retvm_if(*frame == NULL, METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, "Memory allocation failure");
1107                 memcpy(*frame, _frame, _frame_size);
1108                 *size = _frame_size;
1109         } else {
1110                 *frame = NULL;
1111                 *size = 0;
1112         }
1113
1114         return ret;
1115 }
1116
1117 int metadata_extractor_get_frame_at_time(metadata_extractor_h metadata, unsigned long timestamp, bool is_accurate, void **frame, int *size)
1118 {
1119         int ret = METADATA_EXTRACTOR_ERROR_NONE;
1120         metadata_extractor_s *_metadata = (metadata_extractor_s *)metadata;
1121         void *_frame = NULL;
1122         int _frame_size = 0;
1123         int width = 0;
1124         int height = 0;
1125         long long micro_timestamp = 0;
1126
1127         metadata_extractor_retvm_if((!_metadata) || ((!_metadata->path) && (!_metadata->buffer)) || (!size), METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, "Invalid parameter");
1128
1129         micro_timestamp = (long long)timestamp * 1000;
1130
1131         metadata_extractor_debug("accurate [%d] timestamp[%lu] micro_timestamp[%lld]", is_accurate, timestamp, micro_timestamp);
1132
1133         if (_metadata->path)
1134                 ret = mm_file_get_video_frame(_metadata->path, micro_timestamp, is_accurate, (unsigned char **)&_frame, &_frame_size, &width, &height);
1135         else
1136                 ret = mm_file_get_video_frame_from_memory(_metadata->buffer, _metadata->buffer_size, micro_timestamp, is_accurate, (unsigned char **)&_frame, &_frame_size, &width, &height);
1137
1138         metadata_extractor_retv_free_if(ret != FILEINFO_ERROR_NONE, METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, _frame);
1139
1140         if (_frame != NULL) {
1141                 if ((_frame_size > 0)) {
1142                         *frame = _frame;
1143                         *size = _frame_size;
1144                 } else {
1145                         SAFE_FREE(_frame);
1146                         metadata_extractor_error("METADATA_EXTRACTOR_ERROR_OPERATION_FAILED (0x%08x)", METADATA_EXTRACTOR_ERROR_OPERATION_FAILED);
1147                         return METADATA_EXTRACTOR_ERROR_OPERATION_FAILED;
1148                 }
1149         } else {
1150                 *frame = NULL;
1151                 *size = 0;
1152         }
1153
1154         return ret;
1155 }