Fix 64-bit build error
[platform/core/multimedia/libmm-fileinfo.git] / tests / mm_file_test.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 <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdbool.h>
26 #include <glib.h>
27
28 #include <sys/types.h>
29 #include <sys/time.h>
30 #include <unistd.h>
31 #include <inttypes.h>
32
33 #include <mm_file.h>
34 #include "mm_file_debug.h"
35
36 static FILE *msg_tmp_fp = NULL;
37 static struct timeval start, finish;
38 #define MM_TIME_CHECK_START do { \
39                         msg_tmp_fp = fopen("time_check.txt", "a+"); \
40                         gettimeofday(&start, NULL); \
41                 } while(0)
42 #define MM_TIME_CHECK_FINISH(title) do { \
43                         gettimeofday(&finish, NULL); \
44                         int64_t end_time = (finish.tv_sec * 1000 + finish.tv_usec / 1000); \
45                         int64_t start_time = (start.tv_sec * 1000 + start.tv_usec / 1000); \
46                         if (msg_tmp_fp != NULL) { \
47                                 fprintf(msg_tmp_fp, "%s\n", title); \
48                                 fprintf(msg_tmp_fp, " - start_time:   %"PRId64" msec\n", start_time); \
49                                 fprintf(msg_tmp_fp, " - finish_time:  %"PRId64" msec\n", end_time); \
50                                 fprintf(msg_tmp_fp, " - elapsed time: %"PRId64" msec\n", end_time - start_time); \
51                                 fflush(msg_tmp_fp); fclose(msg_tmp_fp); \
52                         } \
53                 } while(0)
54 #define MM_TIME_CHECK_STOP_BY_ERR do { \
55                         if (msg_tmp_fp) { /* opened by MM_TIME_CHECK_START */ \
56                                 fclose(msg_tmp_fp); \
57                                 msg_tmp_fp = NULL; \
58                         } \
59                 } while(0)
60
61 #define SAFE_FREE(src)                  { if (src) {free(src); src = NULL; } }
62
63 typedef struct _mmfile_value {
64         int len;
65         struct {
66                 int i_val;
67                 double d_val;
68                 char *s_val;
69                 void *p_val;
70         } value;
71 } mmfile_value_t;
72
73 typedef struct _TagContext {
74         mmfile_value_t artist;
75         mmfile_value_t title;
76         mmfile_value_t album;
77         mmfile_value_t album_artist;
78         mmfile_value_t genre;
79         mmfile_value_t author;
80         mmfile_value_t copyright;
81         mmfile_value_t date;                    /*string */
82         mmfile_value_t recdate;                 /*string */
83         mmfile_value_t description;
84         mmfile_value_t comment;
85         mmfile_value_t artwork;         /*data */
86         mmfile_value_t artwork_size;    /*int */
87         mmfile_value_t artwork_mime;
88         mmfile_value_t track_num;
89         mmfile_value_t classfication;
90         mmfile_value_t rating;
91         mmfile_value_t conductor;
92         mmfile_value_t longitude;               /*-> double */
93         mmfile_value_t latitude;
94         mmfile_value_t altitude;                /*<-double */
95         mmfile_value_t unsynclyrics;
96         mmfile_value_t synclyrics_size;
97         mmfile_value_t rotate;                  /*string */
98         mmfile_value_t is_spherical;
99         mmfile_value_t is_stitched;
100         mmfile_value_t stitching_software;      /*string */
101         mmfile_value_t projection_type;         /*string */
102         mmfile_value_t stereo_mode;                     /*string */
103         mmfile_value_t source_count;
104         mmfile_value_t init_view_heading;
105         mmfile_value_t init_view_pitch;
106         mmfile_value_t init_view_roll;
107         mmfile_value_t timestamp;
108         mmfile_value_t full_pano_width;
109         mmfile_value_t full_pano_height;
110         mmfile_value_t cropped_area_image_width;
111         mmfile_value_t cropped_area_image_height;
112         mmfile_value_t cropped_area_left;
113         mmfile_value_t cropped_area_top;
114         mmfile_value_t ambisonic_type;
115         mmfile_value_t ambisonic_format;
116         mmfile_value_t ambisonic_order;
117         mmfile_value_t stereo_mode_v2;
118         mmfile_value_t proj_type_v2;
119         mmfile_value_t metadata_source_v2;      /*string */
120         mmfile_value_t pose_yaw_degrees_v2;
121         mmfile_value_t pose_pitch_degrees_v2;
122         mmfile_value_t pose_roll_degrees_v2;
123         mmfile_value_t cbmp_layout_v2;
124         mmfile_value_t cbmp_padding_v2;
125         mmfile_value_t equi_projection_bounds_top_v2;
126         mmfile_value_t equi_projection_bounds_bottom_v2;
127         mmfile_value_t equi_projection_bounds_left_v2;
128         mmfile_value_t equi_projection_bounds_right_v2;
129         mmfile_value_t smta;
130 } TagContext_t;
131
132 typedef struct _ContentContext {
133         int duration;
134         int video_codec;
135         int video_bitrate;
136         int video_fps;
137         int video_w;
138         int video_h;
139         int video_track_id;
140         int video_track_num;
141         int audio_codec;
142         int audio_bitrate;
143         int audio_channel;
144         int audio_samplerate;
145         int audio_track_id;
146         int audio_track_num;
147         int audio_bitpersample;
148         mmfile_value_t thumbnail;
149 } ContentContext_t;
150
151
152 const char *AudioCodecTypeString[] = {
153         "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW",        /* 0~9 */
154         "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",  /* 10~14 */
155         "G711", "G722", "G722.1", "G722.2  (AMR-WB)", "G723 wideband speech",   /* 15~19 */
156         "G726 (ADPCM)", "G728 speech", "G729", "G729a", "G729.1",       /* 20~24 */
157         "Real", "AAC-Low complexity", "AAC-Main profile", "AAC-Scalable sample rate", "AAC-Long term prediction",       /* 25~29 */
158         "AAC-High Efficiency v1", "AAC-High efficiency v2",     "DolbyDigital", "Apple Lossless", "Sony proprietary",   /* 30~34 */
159         "SPEEX", "Vorbis", "AIFF", "AU", "None (will be deprecated)",   /*35~39 */
160         "PCM", "ALAW", "MULAW", "MS ADPCM", "FLAC"      /* 40~44 */
161 };
162
163
164 const char *VideoCodecTypeString[] = {
165         "None (will be deprecated)",    /* 0 */
166         "H263", "H264", "H26L", "MPEG4", "MPEG1",       /* 1~5 */
167         "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2",      /* 6~10 */
168         "H263v2", "H263v3", "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",      /* 11~15 */
169         "MPEG4 part-2 Advanced Simple profile", "MPEG4 part-2 Main profile", "MPEG4 part-2 Core profile", "MPEG4 part-2 Adv Coding Eff profile", "MPEG4 part-2 Adv RealTime Simple profile",    /* 16~20 */
170         "MPEG4 part-10 (h.264)", "Real", "VC-1", "AVS", "Cinepak",      /* 21~25 */
171         "Indeo", "Theora", "Flv", "AV1", /* 26~29 */
172 #ifdef USE_CODEC_VPX
173         "VP8", "VP9"    /*30~31*/
174 #endif
175 };
176
177
178
179 static FILE *fpFailList = NULL;
180
181 static void __get_file_information(const char *path, bool file_test);
182 static void __get_video_frame(const char *path, const char *accurate, bool file_test);
183
184 static bool __read_file(const char *path, unsigned char **data, unsigned int *size)
185 {
186         FILE *fp = NULL;
187         unsigned char *_data = NULL;
188         long _size = 0;
189
190         if (!path || !data || !size) {
191                 printf("Invalid parameter\n");
192                 return false;
193         }
194
195         fp = fopen(path, "r");
196         if (!fp) {
197                 printf("fopen failed (%d)\n", errno);
198                 return false;
199         }
200
201         if (fseek(fp, 0, SEEK_END) < 0) {
202                 printf("fseek failed\n");
203                 goto ERROR;
204         }
205
206         _size = ftell(fp);
207         if (_size <= 0) {
208                 printf("ftell failed\n");
209                 goto ERROR;
210         }
211
212         if (fseek(fp, 0, SEEK_SET) < 0) {
213                 printf("fseek failed\n");
214                 goto ERROR;
215         }
216
217         _data = calloc(1, _size);
218         if (!_data) {
219                 printf("calloc failed\n");
220                 goto ERROR;
221         }
222         if (fread(_data, sizeof(char), _size, fp) != (size_t)_size) {
223                 printf("fread error\n");
224                 goto ERROR;
225         }
226
227         fclose(fp);
228         *data = _data;
229         *size = (unsigned int)_size;
230         printf("file data = %p size = %u\n", *data, *size);
231
232         return true;
233
234 ERROR:
235         SAFE_FREE(_data);
236         fclose(fp);
237
238         return false;
239 }
240
241 static int __bulk_test(int argc, char **argv)
242 {
243         GDir *dir = NULL;
244         GError *error = NULL;
245         char *path = NULL;
246         const char *name;
247
248         dir = g_dir_open(argv[1], 0, &error);
249         if (error != NULL) {
250                 printf("Failed to open directory[%s]\n", argv[1]);
251                 printf("ex) mm_file_test /opt/usr/home/owner/media/Music/ >> result.txt \n");
252                 g_error_free(error);
253                 return 0;
254         }
255
256         while ((name = g_dir_read_name(dir))) {
257                 if (name[0] == '.')
258                         continue;
259
260                 path = g_build_path(G_DIR_SEPARATOR_S, argv[1], name, NULL);
261
262                 if (argc < 3)
263                         __get_file_information(path, true);
264                 else
265                         __get_video_frame(path, argv[2], true);
266
267                 g_free(path);
268         }
269
270         g_dir_close(dir);
271
272         return 0;
273 }
274
275 int main(int argc, char **argv)
276 {
277         bool file_test = true;          /*if you want to test mm_file_create_content_XXX_from_memory() set file_test to false */
278
279         if (g_file_test(argv[1], G_FILE_TEST_IS_DIR))
280                 return __bulk_test(argc, argv);
281
282         if (!g_file_test(argv[1], G_FILE_TEST_IS_REGULAR))
283                 return 0;
284
285         if (fpFailList == NULL)
286                 fpFailList = fopen("/opt/var/log/mmfile_fails.txt", "w");
287
288         if (argc < 3)
289                 __get_file_information(argv[1], file_test);
290         else
291                 __get_video_frame(argv[1], argv[2], file_test);
292
293         if (fpFailList != NULL) {
294                 fflush(fpFailList);
295                 fclose(fpFailList);
296         }
297
298         return 0;/*exit(0); */
299 }
300
301 static void __get_file_information(const char *path, bool file_test)
302 {
303         MMHandleType content_attrs = 0;
304         MMHandleType tag_attrs = 0;
305         int audio_track_num = 0;
306         int video_track_num = 0;
307         int ret = 0;
308
309         MM_TIME_CHECK_START;
310
311         printf("Extracting information for [%s] \n", path);
312         /* get track info */
313         ret = mm_file_get_stream_info(path, &audio_track_num, &video_track_num);
314         if (ret == FILEINFO_ERROR_NONE) {
315                 printf("# audio=%d, video=%d\n", audio_track_num, video_track_num);
316         } else {
317                 printf("Failed to mm_file_get_stream_info() error=[%x]\n", ret);
318         }
319
320         if (file_test) {
321                 /* get content handle */
322                 ret = mm_file_create_content_attrs(&content_attrs, path);
323         } else {
324                 unsigned int file_size = 0;
325                 unsigned char *buffer = NULL;
326                 /* Read file */
327                 if (!__read_file(path, &buffer, &file_size)) {
328                         printf("Failed to __read_file()\n");
329
330                         MM_TIME_CHECK_STOP_BY_ERR;
331                         return;
332                 }
333
334                 ret = mm_file_create_content_attrs_from_memory(&content_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
335                 SAFE_FREE(buffer);
336         }
337
338         if (ret == FILEINFO_ERROR_NONE && content_attrs) {
339                 ContentContext_t ccontent;
340                 memset(&ccontent, 0, sizeof(ContentContext_t));
341
342                 ret = mm_file_get_attrs(content_attrs, MM_FILE_CONTENT_DURATION, &ccontent.duration, NULL);
343                 printf("# duration: %d\n", ccontent.duration);
344
345                 if (ret != FILEINFO_ERROR_NONE)
346                         printf("failed to get attrs\n");
347
348                 if (audio_track_num) {
349                         ret = mm_file_get_attrs(content_attrs,
350                                                                 MM_FILE_CONTENT_AUDIO_CODEC, &ccontent.audio_codec,
351                                                                 MM_FILE_CONTENT_AUDIO_SAMPLERATE, &ccontent.audio_samplerate,
352                                                                 MM_FILE_CONTENT_AUDIO_BITRATE, &ccontent.audio_bitrate,
353                                                                 MM_FILE_CONTENT_AUDIO_CHANNELS, &ccontent.audio_channel,
354                                                                 MM_FILE_CONTENT_AUDIO_TRACK_INDEX, &ccontent.audio_track_id,
355                                                                 MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &ccontent.audio_track_num,
356                                                                 MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, &ccontent.audio_bitpersample,
357                                                                 NULL);
358
359                         if (ret != FILEINFO_ERROR_NONE) {
360                                 printf("failed to get audio attrs\n");
361                         } else {
362                                 printf("[Audio] ----------------------------------------- \n");
363                                 printf("# audio codec: %d ", ccontent.audio_codec);
364                                 printf("[%s]\n", (ccontent.audio_codec >= 0 && ccontent.audio_codec < MM_AUDIO_CODEC_NUM) ? AudioCodecTypeString[ccontent.audio_codec] : "Invalid");
365                                 printf("# audio samplerate: %d Hz\n", ccontent.audio_samplerate);
366                                 printf("# audio bitrate: %d bps\n", ccontent.audio_bitrate);
367                                 printf("# audio channel: %d\n", ccontent.audio_channel);
368                                 printf("# audio track id: %d\n", ccontent.audio_track_id);
369                                 printf("# audio track num: %d\n", ccontent.audio_track_num);
370                                 printf("# audio bit per sample: %d\n", ccontent.audio_bitpersample);
371                         }
372                 }
373
374                 if (video_track_num) {
375                         ret = mm_file_get_attrs(content_attrs,
376                                                                 MM_FILE_CONTENT_VIDEO_CODEC, &ccontent.video_codec,
377                                                                 MM_FILE_CONTENT_VIDEO_BITRATE, &ccontent.video_bitrate,
378                                                                 MM_FILE_CONTENT_VIDEO_FPS, &ccontent.video_fps,
379                                                                 MM_FILE_CONTENT_VIDEO_TRACK_INDEX, &ccontent.video_track_id,
380                                                                 MM_FILE_CONTENT_VIDEO_WIDTH, &ccontent.video_w,
381                                                                 MM_FILE_CONTENT_VIDEO_HEIGHT, &ccontent.video_h,
382                                                                 MM_FILE_CONTENT_VIDEO_THUMBNAIL, &ccontent.thumbnail.value.p_val, &ccontent.thumbnail.len,
383                                                                 NULL);
384
385                         if (ret != FILEINFO_ERROR_NONE) {
386                                 printf("failed to get video attrs\n");
387                         } else {
388                                 printf("[Video] ----------------------------------------- \n");
389                                 printf("# video codec: %d ", ccontent.video_codec);
390                                 printf("[%s]\n", (ccontent.video_codec >= 0 && ccontent.video_codec < MM_VIDEO_CODEC_NUM) ? VideoCodecTypeString[ccontent.video_codec] : "Invalid");
391                                 printf("# video bitrate: %d bps\n", ccontent.video_bitrate);
392                                 printf("# video fps: %d\n", ccontent.video_fps);
393                                 printf("# video track id: %d\n", ccontent.video_track_id);
394                                 printf("# video width/height: %d x %d\n", ccontent.video_w, ccontent.video_h);
395                                 //printf("# video thumbnail: %p\n", ccontent.thumbnail.value.p_val);
396                                 printf("# video thumbnail size: %d\n", ccontent.thumbnail.len);
397                         }
398                 }
399
400                 mm_file_destroy_content_attrs(content_attrs);
401         } else {
402                 printf("Failed to mm_file_create_content_attrs() error=[%x]\n", ret);
403         }
404
405         if (file_test) {
406                 /* get tag handle */
407                 ret = mm_file_create_tag_attrs(&tag_attrs, path);
408         } else {
409                 unsigned int file_size = 0;
410                 unsigned char *buffer = NULL;
411                 /* Read file */
412                 if (!__read_file(path, &buffer, &file_size)) {
413                         printf("Failed to __read_file()\n");
414
415                         MM_TIME_CHECK_STOP_BY_ERR;
416                         return;
417                 }
418
419                 ret = mm_file_create_tag_attrs_from_memory(&tag_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
420                 SAFE_FREE(buffer);
421         }
422
423         if (ret == FILEINFO_ERROR_NONE && tag_attrs) {
424                 TagContext_t ctag;
425                 memset(&ctag, 0, sizeof(TagContext_t));
426                 /* get attributes of tag  */
427                 ret = mm_file_get_attrs(tag_attrs,
428                                                 MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
429                                                 MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
430                                                 MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
431                                                 MM_FILE_TAG_TITLE, &ctag.title.value.s_val, &ctag.title.len,
432                                                 MM_FILE_TAG_GENRE, &ctag.genre.value.s_val, &ctag.genre.len,
433                                                 MM_FILE_TAG_AUTHOR, &ctag.author.value.s_val, &ctag.author.len,
434                                                 MM_FILE_TAG_COPYRIGHT, &ctag.copyright.value.s_val, &ctag.copyright.len,
435                                                 MM_FILE_TAG_DATE, &ctag.date.value.s_val, &ctag.date.len,
436                                                 MM_FILE_TAG_RECDATE, &ctag.recdate.value.s_val, &ctag.recdate.len,
437                                                 MM_FILE_TAG_DESCRIPTION, &ctag.description.value.s_val, &ctag.description.len,
438                                                 MM_FILE_TAG_COMMENT, &ctag.comment.value.s_val, &ctag.comment.len,
439                                                 MM_FILE_TAG_ARTWORK, &ctag.artwork.value.p_val, &ctag.artwork.len,
440                                                 MM_FILE_TAG_ARTWORK_SIZE, &ctag.artwork_size.value.i_val,
441                                                 MM_FILE_TAG_ARTWORK_MIME, &ctag.artwork_mime.value.s_val, &ctag.artwork_mime.len,
442                                                 MM_FILE_TAG_TRACK_NUM, &ctag.track_num.value.s_val, &ctag.track_num.len,
443                                                 MM_FILE_TAG_CLASSIFICATION, &ctag.classfication.value.s_val, &ctag.classfication.len,
444                                                 MM_FILE_TAG_RATING, &ctag.rating.value.s_val, &ctag.rating.len,
445                                                 MM_FILE_TAG_LONGITUDE, &ctag.longitude.value.d_val,
446                                                 MM_FILE_TAG_LATIDUE, &ctag.latitude.value.d_val,
447                                                 MM_FILE_TAG_ALTIDUE, &ctag.altitude.value.d_val,
448                                                 MM_FILE_TAG_CONDUCTOR, &ctag.conductor.value.s_val, &ctag.conductor.len,
449                                                 MM_FILE_TAG_UNSYNCLYRICS, &ctag.unsynclyrics.value.s_val, &ctag.unsynclyrics.len,
450                                                 MM_FILE_TAG_SYNCLYRICS_NUM, &ctag.synclyrics_size.value.i_val,
451                                                 MM_FILE_TAG_ROTATE, &ctag.rotate.value.s_val, &ctag.rotate.len,
452                                                 MM_FILE_TAG_SPHERICAL, &ctag.is_spherical.value.i_val,
453                                                 MM_FILE_TAG_SPHERICAL_STITCHED, &ctag.is_stitched.value.i_val,
454                                                 MM_FILE_TAG_SPHERICAL_STITCHING_SOFTWARE, &ctag.stitching_software.value.s_val, &ctag.stitching_software.len,
455                                                 MM_FILE_TAG_SPHERICAL_PROJECTION_TYPE, &ctag.projection_type.value.s_val, &ctag.projection_type.len,
456                                                 MM_FILE_TAG_SPHERICAL_STEREO_MODE, &ctag.stereo_mode.value.s_val, &ctag.stereo_mode.len,
457                                                 MM_FILE_TAG_SPHERICAL_SOURCE_COUNT, &ctag.source_count.value.i_val,
458                                                 MM_FILE_TAG_SPHERICAL_INIT_VIEW_HEADING, &ctag.init_view_heading.value.i_val,
459                                                 MM_FILE_TAG_SPHERICAL_INIT_VIEW_PITCH, &ctag.init_view_pitch.value.i_val,
460                                                 MM_FILE_TAG_SPHERICAL_INIT_VIEW_ROLL, &ctag.init_view_roll.value.i_val,
461                                                 MM_FILE_TAG_SPHERICAL_TIMESTAMP, &ctag.timestamp.value.i_val,
462                                                 MM_FILE_TAG_SPHERICAL_FULL_PANO_WIDTH, &ctag.full_pano_width.value.i_val,
463                                                 MM_FILE_TAG_SPHERICAL_FULL_PANO_HEIGHT, &ctag.full_pano_height.value.i_val,
464                                                 MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_WIDTH, &ctag.cropped_area_image_width.value.i_val,
465                                                 MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_HEIGHT, &ctag.cropped_area_image_height.value.i_val,
466                                                 MM_FILE_TAG_SPHERICAL_CROPPED_AREA_LEFT, &ctag.cropped_area_left.value.i_val,
467                                                 MM_FILE_TAG_SPHERICAL_CROPPED_AREA_TOP, &ctag.cropped_area_top.value.i_val,
468                                                 MM_FILE_TAG_AMBISONIC_TYPE, &ctag.ambisonic_type.value.i_val,
469                                                 MM_FILE_TAG_AMBISONIC_FORMAT, &ctag.ambisonic_format.value.i_val,
470                                                 MM_FILE_TAG_AMBISONIC_ORDER, &ctag.ambisonic_order.value.i_val,
471                                                 MM_FILE_TAG_SPHERICAL_V2_STEREO_MODE, &ctag.stereo_mode_v2.value.i_val,
472                                                 MM_FILE_TAG_SPHERICAL_V2_METADATA_SOURCE, &ctag.metadata_source_v2.value.s_val, &ctag.metadata_source_v2.len,
473                                                 MM_FILE_TAG_SPHERICAL_V2_PROJ_TYPE, &ctag.proj_type_v2.value.i_val,
474                                                 MM_FILE_TAG_SPHERICAL_V2_POSE_YAW, &ctag.pose_yaw_degrees_v2.value.i_val,
475                                                 MM_FILE_TAG_SPHERICAL_V2_POSE_PITCH, &ctag.pose_pitch_degrees_v2.value.i_val,
476                                                 MM_FILE_TAG_SPHERICAL_V2_POSE_ROLL, &ctag.pose_roll_degrees_v2.value.i_val,
477                                                 MM_FILE_TAG_SPHERICAL_V2_CBMP_LAYOUT, &ctag.cbmp_layout_v2.value.i_val,
478                                                 MM_FILE_TAG_SPHERICAL_V2_CBMP_PADDING, &ctag.cbmp_padding_v2.value.i_val,
479                                                 MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_TOP, &ctag.equi_projection_bounds_top_v2.value.i_val,
480                                                 MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_BOTTOM, &ctag.equi_projection_bounds_bottom_v2.value.i_val,
481                                                 MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_LEFT, &ctag.equi_projection_bounds_left_v2.value.i_val,
482                                                 MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_RIGHT, &ctag.equi_projection_bounds_right_v2.value.i_val,
483                                                 MM_FILE_TAG_SMTA, &ctag.smta.value.i_val,
484                                                 NULL);
485                 if (ret != FILEINFO_ERROR_NONE) {
486                         printf("failed to get attrs\n");
487
488                         MM_TIME_CHECK_STOP_BY_ERR;
489                         mm_file_destroy_tag_attrs(tag_attrs);
490                         return;
491                 }
492
493                 /* print tag information         */
494                 printf("[Tag] =================================== \n");
495                 printf("# artist: [%s]\n", ctag.artist.value.s_val);
496                 printf("# title: [%s]\n", ctag.title.value.s_val);
497                 printf("# album: [%s]\n", ctag.album.value.s_val);
498                 printf("# album_artist: [%s]\n", ctag.album_artist.value.s_val);
499                 printf("# genre: [%s]\n", ctag.genre.value.s_val);
500                 printf("# author: [%s]\n", ctag.author.value.s_val);
501                 printf("# copyright: [%s]\n", ctag.copyright.value.s_val);
502                 printf("# year: [%s]\n", ctag.date.value.s_val);
503                 printf("# recdate: [%s]\n", ctag.recdate.value.s_val);
504                 printf("# description: [%s]\n", ctag.description.value.s_val);
505                 printf("# comment: [%s]\n", ctag.comment.value.s_val);
506                 //printf("# artwork: [%p]\n", ctag.artwork.value.p_val);
507                 printf("# artwork_size: [%d]\n", ctag.artwork_size.value.i_val);
508                 printf("# artwork_mime: [%s]\n", ctag.artwork_mime.value.s_val);
509                 printf("# track number: [%s]\n", ctag.track_num.value.s_val);
510                 printf("# classification: [%s]\n", ctag.classfication.value.s_val);
511                 printf("# rating: [%s]\n", ctag.rating.value.s_val);
512                 printf("# longitude: [%f]\n", ctag.longitude.value.d_val);
513                 printf("# latitude: [%f]\n", ctag.latitude.value.d_val);
514                 printf("# altitude: [%f]\n", ctag.altitude.value.d_val);
515                 printf("# conductor: [%s]\n", ctag.conductor.value.s_val);
516                 printf("# unsynclyrics_length: [%d]\n", ctag.unsynclyrics.len);
517                 printf("# unsynclyrics: [%s]\n", ctag.unsynclyrics.value.s_val);
518                 printf("# synclyrics size: [%d]\n", ctag.synclyrics_size.value.i_val);
519                 printf("# rotate: [%s]\n", ctag.rotate.value.s_val);
520                 printf("# is_spherical: [%d]\n", ctag.is_spherical.value.i_val);
521                 printf("# is_stitched: [%d]\n", ctag.is_stitched.value.i_val);
522
523                 if (ctag.is_spherical.value.i_val > 0 && ctag.is_stitched.value.i_val > 0) {
524                         printf("# stitching_software: [%s]\n", ctag.stitching_software.value.s_val);
525                         printf("# projection_type: [%s]\n", ctag.projection_type.value.s_val);
526                         printf("# stereo_mode [%s]\n", ctag.stereo_mode.value.s_val);
527                         printf("# source_count: [%d]\n", ctag.source_count.value.i_val);
528                         printf("# init_view_heading: [%d]\n", ctag.init_view_heading.value.i_val);
529                         printf("# init_view_pitch: [%d]\n", ctag.init_view_pitch.value.i_val);
530                         printf("# init_view_roll: [%d]\n", ctag.init_view_roll.value.i_val);
531                         printf("# time_stamp: [%d]\n", ctag.timestamp.value.i_val);
532                         printf("# full_pano_width: [%d]\n", ctag.full_pano_width.value.i_val);
533                         printf("# full_pano_height: [%d]\n", ctag.full_pano_height.value.i_val);
534                         printf("# cropped_area_image_width: [%d]\n", ctag.cropped_area_image_width.value.i_val);
535                         printf("# cropped_area_image_height: [%d]\n", ctag.cropped_area_image_height.value.i_val);
536                         printf("# cropped_area_left: [%d]\n", ctag.cropped_area_left.value.i_val);
537                         printf("# cropped_area_top: [%d]\n", ctag.cropped_area_top.value.i_val);
538                 }
539
540                 printf("# ambisonic_type: [%d]\n", ctag.ambisonic_type.value.i_val);
541
542                 if (ctag.ambisonic_type.value.i_val > 0) {
543                         printf("# ambisonic_format: [%d]\n", ctag.ambisonic_format.value.i_val);
544                         printf("# ambisonic_order: [%d]\n", ctag.ambisonic_order.value.i_val);
545                 }
546
547                 printf("# stereo_mode_v2: [%d]\n", ctag.stereo_mode_v2.value.i_val);
548
549                 if (ctag.proj_type_v2.value.i_val >= 0) {
550                         printf("# proj_type_v2: [%d]\n", ctag.proj_type_v2.value.i_val);
551                         printf("# metadata_source_v2: [%s]\n", ctag.metadata_source_v2.value.s_val);
552                         printf("# pose_yaw_degrees_v2: [%d]\n", ctag.pose_yaw_degrees_v2.value.i_val);
553                         printf("# pose_pitch_degrees_v2: [%d]\n", ctag.pose_pitch_degrees_v2.value.i_val);
554                         printf("# pose_roll_degrees_v2: [%d]\n", ctag.pose_roll_degrees_v2.value.i_val);
555                         printf("# cbmp_layout_v2: [%d]\n", ctag.cbmp_layout_v2.value.i_val);
556                         printf("# cbmp_padding_v2: [%d]\n", ctag.cbmp_padding_v2.value.i_val);
557                         printf("# equi_projection_bounds_top_v2: [%d]\n", ctag.equi_projection_bounds_top_v2.value.i_val);
558                         printf("# equi_projection_bounds_bottom_v2: [%d]\n", ctag.equi_projection_bounds_bottom_v2.value.i_val);
559                         printf("# equi_projection_bounds_left_v2: [%d]\n", ctag.equi_projection_bounds_left_v2.value.i_val);
560                         printf("# equi_projection_bounds_right_v2: [%d]\n", ctag.equi_projection_bounds_right_v2.value.i_val);
561                 }
562
563                 printf("# smta: [%d]\n", ctag.smta.value.i_val);
564
565                 if (ctag.synclyrics_size.value.i_val > 0) {
566                         int idx = 0;
567                         unsigned long time_info = 0;
568                         char *lyrics_info = NULL;
569
570                         printf("# synclyrics: \n");
571
572                         for (idx = 0; idx < ctag.synclyrics_size.value.i_val; idx++) {
573                                 ret = mm_file_get_synclyrics_info(tag_attrs, idx, &time_info, &lyrics_info);
574                                 if (ret == FILEINFO_ERROR_NONE) {
575                                         printf("[%2d][%6ld][%s]\n", idx, time_info, lyrics_info);
576                                 } else {
577                                         printf("Error when get lyrics\n");
578                                         break;
579                                 }
580                         }
581                 }
582
583                 /* release tag */
584                 ret = mm_file_destroy_tag_attrs(tag_attrs);
585                 if (ret != FILEINFO_ERROR_NONE) {
586                         printf("Error mm_file_destroy_tag_attrs: %d", ret);
587                         MM_TIME_CHECK_STOP_BY_ERR;
588                         return;
589                 }
590         } else {
591                 printf("Failed to mm_file_create_tag_attrs() error=[%x]\n", ret);
592         }
593
594
595         printf("=================================================\n\n");
596
597         MM_TIME_CHECK_FINISH(path);
598 }
599
600 static void __get_video_frame(const char *path, const char *accurate, bool file_test)
601 {
602         int ret = 0;
603         unsigned char *_frame = NULL;
604         int _frame_size = 0;
605         int width = 0;
606         int height = 0;
607         bool is_accurate = false;
608         int64_t time_stamp = 5 * 1000 * 1000;           //5sec
609
610         if (accurate && accurate[0] == '1')
611                 is_accurate = true;
612
613         printf("Extracting video frame for [%s] [%"PRId64"] accurate [%d]\n", path, time_stamp, is_accurate);
614
615         if (file_test)
616                 ret = mm_file_get_video_frame(path, time_stamp, is_accurate, &_frame, &_frame_size, &width, &height);
617         else    {
618                 unsigned int file_size = 0;
619                 unsigned char *buffer = NULL;
620                 /* Read file */
621                 if (!__read_file(path, &buffer, &file_size)) {
622                         printf("Failed to __read_file()\n");
623                         return;
624                 }
625
626                 ret = mm_file_get_video_frame_from_memory(buffer, file_size, time_stamp, is_accurate, &_frame, &_frame_size, &width, &height);
627                 SAFE_FREE(buffer);
628         }
629
630         if (ret != FILEINFO_ERROR_NONE)
631                 printf("Failed to mm_file_get_video_frame() error=[%x]\n", ret);
632         else
633                 printf("video_frame[%p], video_frame_len = [%d] width = [%d] height = [%d]\n", _frame, _frame_size, width, height);
634
635         SAFE_FREE(_frame);
636 }