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