support album art.
[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_error.h>
34
35 #include "mm_file_traverse.h"
36
37 #define MM_TIME_CHECK_START \
38 { FILE *msg_tmp_fp = fopen("time_check.txt", "a+"); struct timeval start, finish; gettimeofday(&start, NULL);
39 #define MM_TIME_CHECK_FINISH(title) \
40 gettimeofday(&finish, NULL); \
41 double end_time = (finish.tv_sec + 1e-6*finish.tv_usec); \
42 double start_time = (start.tv_sec + 1e-6*start.tv_usec); \
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 description;
70         mmfile_value_t comment;
71         mmfile_value_t artwork;         //data
72         mmfile_value_t artwork_size;    //int
73         mmfile_value_t artwork_mime;
74         mmfile_value_t track_num;
75         mmfile_value_t classfication;
76         mmfile_value_t rating;
77         mmfile_value_t conductor;
78         mmfile_value_t longitude;               //-> double
79         mmfile_value_t latitude;                
80         mmfile_value_t altitude;                //<-double
81         mmfile_value_t unsynclyrics;
82         mmfile_value_t synclyrics_size;
83         mmfile_value_t rotate;                  //string
84 }TagContext_t;
85
86 typedef struct _ContentContext {
87         int duration;
88         int video_codec;
89         int video_bitrate;
90         int video_fps;
91         int video_w;
92         int video_h;
93         int video_track_id;
94         int video_track_num;
95         int audio_codec;
96         int audio_bitrate;
97         int audio_channel;
98         int audio_samplerate;
99         int audio_track_id;
100         int audio_track_num;
101         mmfile_value_t thumbnail;
102 }ContentContext_t;
103
104
105 char * AudioCodecTypeString [] = {
106         "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW", "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",
107         "G711", "G722", "G722.1",       "G722.2  (AMR-WB)",     "G723 wideband speech", "G726 (ADPCM)", "G728 speech",  "G729", "G729a",        "G729.1",
108         "Real",
109         "AAC-Low complexity",   "AAC-Main profile",     "AAC-Scalable sample rate",     "AAC-Long term prediction",     "AAC-High Efficiency v1",       "AAC-High efficiency v2",
110         "DolbyDigital", "Apple Lossless",       "Sony proprietary",     "SPEEX",        "Vorbis",       "AIFF", "AU",   "None (will be deprecated)",
111         "PCM",  "ALAW", "MULAW",        "MS ADPCM",     "FLAC"
112 };
113
114
115 char * VideoCodecTypeString [] = {
116         "None (will be deprecated)",
117         "H263", "H264", "H26L", "MPEG4", "MPEG1", "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2", "H263v2",  "H263v3",
118         "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",  "MPEG4 part-2 Advanced Simple profile", "MPEG4 part-2 Main profile",
119         "MPEG4 part-2 Core profile", "MPEG4 part-2 Adv Coding Eff profile",     "MPEG4 part-2 Adv RealTime Simple profile",
120         "MPEG4 part-10 (h.264)",        "Real", "VC-1", "AVS",  "Cinepak",      "Indeo",        "Theora", "Flv"
121 };
122
123
124
125 FILE *fpFailList = NULL;
126
127 static int mmfile_get_file_infomation (void *data, void* user_data, bool file_test);
128
129 inline static int mm_file_is_little_endian (void)
130 {
131     int i = 0x00000001;
132     return ((char *)&i)[0];
133 }
134
135 #define READ_FROM_FILE(FILE_PATH, data, size) \
136 do{     \
137         FILE * fp = fopen (FILE_PATH, "r");     \
138         if (fp) {       \
139                         fseek (fp, 0, SEEK_END);        \
140                         size = ftell(fp);       \
141                         fseek (fp, 0, SEEK_SET);        \
142                         data = malloc (size);   \
143                         if (fread (data, size, sizeof(char), fp) != size) { printf("fread error\n"); }  \
144                         fclose (fp);    \
145                         printf("file size = %d\n", size );      \
146         }       \
147 }while(0)
148
149 static int
150 _is_file_exist (const char *filename)
151 {
152         int ret = 1;
153         if (filename) {
154                 const char* to_access = (strstr(filename,"file://")!=NULL)? filename+7:filename;
155                 ret = access (to_access, R_OK );
156                 if (ret != 0) {
157                         printf  ("file [%s] not found.\n", to_access);
158                 }
159         }
160         return !ret;
161 }
162
163
164 int main(int argc, char **argv)
165 {
166     struct stat statbuf;
167         bool file_test = true;          //if you want to test mm_file_create_content_XXX_from_memory() set file_test to false
168
169     if (_is_file_exist (argv[1])) {
170         int ret = lstat (argv[1], &statbuf);
171             if ( ret < 0 ) {
172                 printf ("lstat error[%d]\n", ret);
173                 return MMFILE_FAIL;
174         }
175
176                 if (fpFailList == NULL) {
177                         fpFailList = fopen ("/opt/var/log/mmfile_fails.txt", "w");
178                 }
179
180                 if ( S_ISDIR (statbuf.st_mode) )        {
181                         mmfile_get_file_names (argv[1], mmfile_get_file_infomation, NULL);
182                 } else {
183                         mmfile_get_file_infomation (argv[1], NULL, file_test);
184                 }
185
186                 if (fpFailList != NULL) {
187                         fflush (fpFailList);
188                         fclose (fpFailList);
189                 }
190     }
191
192     exit(0);
193 }
194
195 static int mmfile_get_file_infomation (void *data, void* user_data, bool file_test)
196 {
197         MMHandleType content_attrs = 0;
198         MMHandleType tag_attrs = 0;
199         char *err_attr_name = NULL;
200         int audio_track_num = 0;
201         int video_track_num = 0;
202         int ret = 0;
203         char filename[512];
204
205         memset (filename, 0x00, 512);
206         memcpy (filename, (char*)data, strlen ((char*)data));
207
208         MM_TIME_CHECK_START
209
210         printf ("Extracting information for [%s] \n", filename);
211         /* get track info */
212         ret = mm_file_get_stream_info(filename, &audio_track_num, &video_track_num);
213         if (ret == MM_ERROR_NONE) {
214                 printf ("# audio=%d, video=%d\n", audio_track_num, video_track_num);
215         } else {
216                 printf ("Failed to mm_file_get_stream_info() error=[%x]\n", ret);
217         }
218
219         if(file_test) {
220                 /* get content handle */
221                 ret = mm_file_create_content_attrs(&content_attrs, filename);
222         } else {
223                 int file_size = 0;
224                 unsigned char * buffer = NULL;
225                 /* Read file */
226                 READ_FROM_FILE(filename, buffer, file_size);
227
228                 ret =mm_file_create_content_attrs_from_memory(&content_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
229         }
230
231         if (ret == MM_ERROR_NONE && content_attrs) {
232                 ContentContext_t ccontent;
233                 memset (&ccontent, 0, sizeof (ContentContext_t));
234
235                 ret = mm_file_get_attrs(content_attrs, &err_attr_name, MM_FILE_CONTENT_DURATION, &ccontent.duration, NULL);
236                 printf("# duration: %d\n", ccontent.duration);
237
238                 if (ret != MM_ERROR_NONE && err_attr_name)
239                 {
240                         printf("failed to get %s\n", err_attr_name);
241                         free(err_attr_name);
242                         err_attr_name = NULL;
243                 }
244
245                 if (audio_track_num)
246                 {
247                         ret = mm_file_get_attrs(content_attrs,
248                                                                         NULL,
249                                                                         MM_FILE_CONTENT_AUDIO_CODEC, &ccontent.audio_codec,
250                                                                         MM_FILE_CONTENT_AUDIO_SAMPLERATE, &ccontent.audio_samplerate,
251                                                                         MM_FILE_CONTENT_AUDIO_BITRATE, &ccontent.audio_bitrate,
252                                                                         MM_FILE_CONTENT_AUDIO_CHANNELS, &ccontent.audio_channel,
253                                                                         MM_FILE_CONTENT_AUDIO_TRACK_INDEX, &ccontent.audio_track_id,
254                                                                         MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &ccontent.audio_track_num,
255                                                                         NULL);
256
257                         if(ret != MM_ERROR_NONE) {
258                                 printf("failed to get audio attrs\n");
259                         } else {
260                                 printf ("[Audio] ----------------------------------------- \n");
261                                 printf("# audio codec: %d ", ccontent.audio_codec);
262                                 printf ("[%s]\n", (ccontent.audio_codec >= 0 && ccontent.audio_codec < MM_AUDIO_CODEC_NUM)? AudioCodecTypeString[ccontent.audio_codec] : "Invalid");
263                                 printf("# audio samplerate: %d Hz\n", ccontent.audio_samplerate);
264                                 printf("# audio bitrate: %d bps\n", ccontent.audio_bitrate);
265                                 printf("# audio channel: %d\n", ccontent.audio_channel);
266                                 printf("# audio track id: %d\n", ccontent.audio_track_id);
267                                 printf("# audio track num: %d\n", ccontent.audio_track_num);
268                         }
269                 }
270         
271                 if (video_track_num)
272                 {
273                         ret = mm_file_get_attrs(content_attrs,
274                                                                         NULL,
275                                                                         MM_FILE_CONTENT_VIDEO_CODEC, &ccontent.video_codec,
276                                                                         MM_FILE_CONTENT_VIDEO_BITRATE, &ccontent.video_bitrate,
277                                                                         MM_FILE_CONTENT_VIDEO_FPS, &ccontent.video_fps,
278                                                                         MM_FILE_CONTENT_VIDEO_TRACK_INDEX, &ccontent.video_track_id,
279                                                                         MM_FILE_CONTENT_VIDEO_WIDTH, &ccontent.video_w,
280                                                                         MM_FILE_CONTENT_VIDEO_HEIGHT, &ccontent.video_h,
281                                                                         MM_FILE_CONTENT_VIDEO_THUMBNAIL, &ccontent.thumbnail.value.p_val, &ccontent.thumbnail.len,
282                                                                         NULL);
283
284                         if(ret != MM_ERROR_NONE) {
285                                 printf("failed to get video attrs\n");
286                         } else {
287                                 printf ("[Video] ----------------------------------------- \n");
288                                 printf("# video codec: %d ", ccontent.video_codec);
289                                 printf ("[%s]\n", (ccontent.video_codec >= 0 && ccontent.video_codec < MM_VIDEO_CODEC_NUM)? VideoCodecTypeString[ccontent.video_codec] : "Invalid");
290                                 printf("# video bitrate: %d bps\n", ccontent.video_bitrate);
291                                 printf("# video fps: %d\n", ccontent.video_fps);
292                                 printf("# video track id: %d\n", ccontent.video_track_id);
293                                 printf("# video width/height: %d x %d\n", ccontent.video_w, ccontent.video_h);
294                                 printf("# video thumbnail: %p\n", ccontent.thumbnail.value.p_val);
295                         }
296                 }
297
298                 mm_file_destroy_content_attrs(content_attrs);
299         } else {
300                 printf ("Failed to mm_file_create_content_attrs() error=[%x]\n", ret);
301         }
302
303         if(file_test) {
304                 /* get tag handle */
305                 ret = mm_file_create_tag_attrs(&tag_attrs, filename);
306         } else {
307                 int file_size = 0;
308                 unsigned char * buffer = NULL;
309                 /* Read file */
310                 READ_FROM_FILE(filename, buffer, file_size);
311
312                 ret =mm_file_create_tag_attrs_from_memory(&tag_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
313         }
314
315         if (ret == MM_ERROR_NONE && tag_attrs) {
316                 TagContext_t ctag;
317                 memset (&ctag, 0, sizeof (TagContext_t));
318                 /* get attributes of tag  */
319                 ret = mm_file_get_attrs( tag_attrs,
320                                                                         &err_attr_name,
321                                                                         MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
322                                                                         MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
323                                                                         MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
324                                                                         MM_FILE_TAG_TITLE, &ctag.title.value.s_val, &ctag.title.len,
325                                                                         MM_FILE_TAG_GENRE, &ctag.genre.value.s_val, &ctag.genre.len,
326                                                                         MM_FILE_TAG_AUTHOR, &ctag.author.value.s_val, &ctag.author.len,
327                                                                         MM_FILE_TAG_COPYRIGHT, &ctag.copyright.value.s_val, &ctag.copyright.len,
328                                                                         MM_FILE_TAG_DATE, &ctag.date.value.s_val, &ctag.date.len,
329                                                                         MM_FILE_TAG_RECDATE, &ctag.recdate.value.s_val, &ctag.recdate.len,
330                                                                         MM_FILE_TAG_DESCRIPTION, &ctag.description.value.s_val, &ctag.description.len,
331                                                                         MM_FILE_TAG_COMMENT, &ctag.comment.value.s_val, &ctag.comment.len,
332                                                                         MM_FILE_TAG_ARTWORK, &ctag.artwork.value.p_val, &ctag.artwork.len,
333                                                                         MM_FILE_TAG_ARTWORK_SIZE, &ctag.artwork_size.value.i_val,
334                                                                         MM_FILE_TAG_ARTWORK_MIME, &ctag.artwork_mime.value.s_val, &ctag.artwork_mime.len,
335                                                                         MM_FILE_TAG_TRACK_NUM, &ctag.track_num.value.s_val, &ctag.track_num.len,
336                                                                         MM_FILE_TAG_CLASSIFICATION, &ctag.classfication.value.s_val, &ctag.classfication.len,
337                                                                         MM_FILE_TAG_RATING, &ctag.rating.value.s_val, &ctag.rating.len,
338                                                                         MM_FILE_TAG_LONGITUDE, &ctag.longitude.value.d_val,
339                                                                         MM_FILE_TAG_LATIDUE, &ctag.latitude.value.d_val,
340                                                                         MM_FILE_TAG_ALTIDUE, &ctag.altitude.value.d_val,
341                                                                         MM_FILE_TAG_CONDUCTOR, &ctag.conductor.value.s_val, &ctag.conductor.len,
342                                                                         MM_FILE_TAG_UNSYNCLYRICS, &ctag.unsynclyrics.value.s_val, &ctag.unsynclyrics.len,
343                                                                         MM_FILE_TAG_SYNCLYRICS_NUM, &ctag.synclyrics_size.value.i_val,
344                                                                         MM_FILE_TAG_ROTATE, &ctag.rotate.value.s_val, &ctag.rotate.len,
345                                                                         NULL);
346                 if (ret != MM_ERROR_NONE &&  err_attr_name)
347                 {
348                         printf("failed to get %s attrs\n", err_attr_name);
349                         free(err_attr_name);
350                         err_attr_name = NULL;
351
352                         if (msg_tmp_fp) /* opened by MM_TIME_CHECK_START */
353                         {
354                                 fclose (msg_tmp_fp);
355                                 msg_tmp_fp = NULL;
356                         }
357
358                         return -1;
359                 }
360
361                 /* print tag information         */
362                 printf ("[Tag] =================================== \n");
363                 printf("# artist: [%s]\n", ctag.artist.value.s_val);
364                 printf("# title: [%s]\n", ctag.title.value.s_val);
365                 printf("# album: [%s]\n", ctag.album.value.s_val);
366                 printf("# album_artist: [%s]\n", ctag.album_artist.value.s_val);
367                 printf("# genre: [%s]\n", ctag.genre.value.s_val);
368                 printf("# author: [%s]\n", ctag.author.value.s_val);
369                 printf("# copyright: [%s]\n", ctag.copyright.value.s_val);
370                 printf("# year: [%s]\n", ctag.date.value.s_val);
371                 printf("# recdate: [%s]\n", ctag.recdate.value.s_val);
372                 printf("# description: [%s]\n", ctag.description.value.s_val);
373                 printf("# comment: [%s]\n", ctag.comment.value.s_val);
374                 printf("# artwork: [%p]\n", ctag.artwork.value.p_val);
375                 printf("# artwork_size: [%d]\n", ctag.artwork_size.value.i_val);
376                 printf("# artwork_mime: [%s]\n", ctag.artwork_mime.value.s_val);
377                 printf("# track number: [%s]\n", ctag.track_num.value.s_val);
378                 printf("# classification: [%s]\n", ctag.classfication.value.s_val);
379                 printf("# rating: [%s]\n", ctag.rating.value.s_val);
380                 printf("# longitude: [%f]\n", ctag.longitude.value.d_val);
381                 printf("# latitude: [%f]\n", ctag.latitude.value.d_val);
382                 printf("# altitude: [%f]\n", ctag.altitude.value.d_val);
383                 printf("# conductor: [%s]\n", ctag.conductor.value.s_val);
384                 printf("# unsynclyrics_length: [%d]\n", ctag.unsynclyrics.len);
385                 printf("# unsynclyrics: [%s]\n", ctag.unsynclyrics.value.s_val);
386                 printf("# synclyrics size: [%d]\n", ctag.synclyrics_size.value.i_val);
387                 printf("# rotate: [%s]\n", ctag.rotate.value.s_val);
388
389                 if(ctag.synclyrics_size.value.i_val > 0) {
390                         int idx = 0;
391                         unsigned long time_info = 0;
392                         char * lyrics_info = NULL;
393
394                         printf("# synclyrics: \n");
395                         
396                         for(idx = 0; idx < ctag.synclyrics_size.value.i_val; idx++) {
397                                 ret = mm_file_get_synclyrics_info(tag_attrs, idx, &time_info, &lyrics_info);
398                                 if(ret == MM_ERROR_NONE) {
399                                         printf("[%2d][%6ld][%s]\n", idx, time_info, lyrics_info);
400                                 } else {
401                                         printf("Error when get lyrics\n");
402                                         break;
403                                 }
404                         }
405                 }
406                 
407                 /* release tag */
408                 mm_file_destroy_tag_attrs(tag_attrs);
409         } else {
410                 printf ("Failed to mm_file_create_tag_attrs() error=[%x]\n", ret);
411         }
412
413
414         printf ("=================================================\n\n");
415
416         MM_TIME_CHECK_FINISH (filename);
417
418     return 0;
419 }