Remove test code for directory support
[platform/core/multimedia/libmm-fileinfo.git] / tests / mm_file_test.c
index 455287d..62b31ce 100755 (executable)
 #include <unistd.h>
 
 #include <mm_file.h>
-#include <mm_error.h>
-
-#include "mm_file_traverse.h"
-
-#define MM_TIME_CHECK_START \
-{ FILE *msg_tmp_fp = fopen("time_check.txt", "a+"); struct timeval start, finish; gettimeofday(&start, NULL);
-#define MM_TIME_CHECK_FINISH(title) \
-gettimeofday(&finish, NULL); \
-double end_time = (finish.tv_sec + 1e-6*finish.tv_usec); \
-double start_time = (start.tv_sec + 1e-6*start.tv_usec); \
-if(msg_tmp_fp != NULL) { \
-fprintf(msg_tmp_fp, "%s\n", title); \
-fprintf(msg_tmp_fp, " - start_time:   %3.5lf sec\n", start_time); \
-fprintf(msg_tmp_fp, " - finish_time:  %3.5lf sec\n", end_time); \
-fprintf(msg_tmp_fp, " - elapsed time: %3.5lf sec\n", end_time - start_time); \
-fflush(msg_tmp_fp); fclose(msg_tmp_fp); }}
+#include "mm_file_debug.h"
+
+static FILE *msg_tmp_fp = NULL;
+static struct timeval start, finish;
+#define MM_TIME_CHECK_START do { \
+                       msg_tmp_fp = fopen("time_check.txt", "a+"); \
+                       gettimeofday(&start, NULL); \
+               } while(0)
+#define MM_TIME_CHECK_FINISH(title) do { \
+                       gettimeofday(&finish, NULL); \
+                       double end_time = (finish.tv_sec + 1e-6*finish.tv_usec); \
+                       double start_time = (start.tv_sec + 1e-6*start.tv_usec); \
+                       if (msg_tmp_fp != NULL) { \
+                               fprintf(msg_tmp_fp, "%s\n", title); \
+                               fprintf(msg_tmp_fp, " - start_time:   %3.5lf sec\n", start_time); \
+                               fprintf(msg_tmp_fp, " - finish_time:  %3.5lf sec\n", end_time); \
+                               fprintf(msg_tmp_fp, " - elapsed time: %3.5lf sec\n", end_time - start_time); \
+                               fflush(msg_tmp_fp); fclose(msg_tmp_fp); \
+                       } \
+               } while(0)
+#define MM_TIME_CHECK_STOP_BY_ERR do { \
+                       if (msg_tmp_fp) { /* opened by MM_TIME_CHECK_START */ \
+                               fclose(msg_tmp_fp); \
+                               msg_tmp_fp = NULL; \
+                       } \
+               } while(0)
+
+#define SAFE_FREE(src)                 { if (src) {free(src); src = NULL; } }
 
 typedef struct _mmfile_value {
        int len;
@@ -54,8 +66,8 @@ typedef struct _mmfile_value {
                double d_val;
                char *s_val;
                void *p_val;
-       }value;
-}mmfile_value_t;
+       } value;
+} mmfile_value_t;
 
 typedef struct _TagContext {
        mmfile_value_t artist;
@@ -65,24 +77,57 @@ typedef struct _TagContext {
        mmfile_value_t genre;
        mmfile_value_t author;
        mmfile_value_t copyright;
-       mmfile_value_t date;                    //string
-       mmfile_value_t recdate;                 //string
+       mmfile_value_t date;                    /*string */
+       mmfile_value_t recdate;                 /*string */
+       mmfile_value_t part_of_set;                     /*string */
        mmfile_value_t description;
        mmfile_value_t comment;
-       mmfile_value_t artwork;         //data
-       mmfile_value_t artwork_size;    //int
+       mmfile_value_t artwork;         /*data */
+       mmfile_value_t artwork_size;    /*int */
        mmfile_value_t artwork_mime;
        mmfile_value_t track_num;
        mmfile_value_t classfication;
        mmfile_value_t rating;
        mmfile_value_t conductor;
-       mmfile_value_t longitude;               //-> double
-       mmfile_value_t latitude;                
-       mmfile_value_t altitude;                //<-double
+       mmfile_value_t longitude;               /*-> double */
+       mmfile_value_t latitude;
+       mmfile_value_t altitude;                /*<-double */
        mmfile_value_t unsynclyrics;
        mmfile_value_t synclyrics_size;
-       mmfile_value_t rotate;                  //string
-}TagContext_t;
+       mmfile_value_t rotate;                  /*string */
+       mmfile_value_t is_spherical;
+       mmfile_value_t is_stitched;
+       mmfile_value_t stitching_software;      /*string */
+       mmfile_value_t projection_type;         /*string */
+       mmfile_value_t stereo_mode;                     /*string */
+       mmfile_value_t source_count;
+       mmfile_value_t init_view_heading;
+       mmfile_value_t init_view_pitch;
+       mmfile_value_t init_view_roll;
+       mmfile_value_t timestamp;
+       mmfile_value_t full_pano_width;
+       mmfile_value_t full_pano_height;
+       mmfile_value_t cropped_area_image_width;
+       mmfile_value_t cropped_area_image_height;
+       mmfile_value_t cropped_area_left;
+       mmfile_value_t cropped_area_top;
+       mmfile_value_t ambisonic_type;
+       mmfile_value_t ambisonic_format;
+       mmfile_value_t ambisonic_order;
+       mmfile_value_t stereo_mode_v2;
+       mmfile_value_t proj_type_v2;
+       mmfile_value_t metadata_source_v2;      /*string */
+       mmfile_value_t pose_yaw_degrees_v2;
+       mmfile_value_t pose_pitch_degrees_v2;
+       mmfile_value_t pose_roll_degrees_v2;
+       mmfile_value_t cbmp_layout_v2;
+       mmfile_value_t cbmp_padding_v2;
+       mmfile_value_t equi_projection_bounds_top_v2;
+       mmfile_value_t equi_projection_bounds_bottom_v2;
+       mmfile_value_t equi_projection_bounds_left_v2;
+       mmfile_value_t equi_projection_bounds_right_v2;
+       mmfile_value_t smta;
+} TagContext_t;
 
 typedef struct _ContentContext {
        int duration;
@@ -101,172 +146,205 @@ typedef struct _ContentContext {
        int audio_track_num;
        int audio_bitpersample;
        mmfile_value_t thumbnail;
-}ContentContext_t;
-
-
-char * AudioCodecTypeString [] = {
-       "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW",        // 0~9
-       "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",  // 10~14
-       "G711", "G722", "G722.1", "G722.2  (AMR-WB)", "G723 wideband speech",   // 15~19
-       "G726 (ADPCM)", "G728 speech", "G729", "G729a", "G729.1",       // 20~24
-       "Real", "AAC-Low complexity", "AAC-Main profile", "AAC-Scalable sample rate", "AAC-Long term prediction",       // 25~29
-       "AAC-High Efficiency v1", "AAC-High efficiency v2",     "DolbyDigital", "Apple Lossless", "Sony proprietary",   // 30~34
-       "SPEEX", "Vorbis", "AIFF", "AU", "None (will be deprecated)",   //35~39
-       "PCM", "ALAW", "MULAW", "MS ADPCM", "FLAC"      // 40~44
+} ContentContext_t;
+
+
+const char *AudioCodecTypeString[] = {
+       "AMR", "G723.1", "MP3", "OGG", "AAC", "WMA", "MMF", "ADPCM", "WAVE", "WAVE NEW",        /* 0~9 */
+       "MIDI", "IMELODY", "MXMF", "MPEG1-Layer1 codec", "MPEG1-Layer2 codec",  /* 10~14 */
+       "G711", "G722", "G722.1", "G722.2  (AMR-WB)", "G723 wideband speech",   /* 15~19 */
+       "G726 (ADPCM)", "G728 speech", "G729", "G729a", "G729.1",       /* 20~24 */
+       "Real", "AAC-Low complexity", "AAC-Main profile", "AAC-Scalable sample rate", "AAC-Long term prediction",       /* 25~29 */
+       "AAC-High Efficiency v1", "AAC-High efficiency v2",     "DolbyDigital", "Apple Lossless", "Sony proprietary",   /* 30~34 */
+       "SPEEX", "Vorbis", "AIFF", "AU", "None (will be deprecated)",   /*35~39 */
+       "PCM", "ALAW", "MULAW", "MS ADPCM", "FLAC"      /* 40~44 */
 };
 
 
-char * VideoCodecTypeString [] = {
-       "None (will be deprecated)",    // 0
-       "H263", "H264", "H26L", "MPEG4", "MPEG1",       // 1~5
-       "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2",      // 6~10
-       "H263v2", "H263v3", "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",      // 11~15
-       "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
-       "MPEG4 part-10 (h.264)", "Real", "VC-1", "AVS", "Cinepak",      // 21~25
-       "Indeo", "Theora", "Flv"        // 26~28
+const char *VideoCodecTypeString[] = {
+       "None (will be deprecated)",    /* 0 */
+       "H263", "H264", "H26L", "MPEG4", "MPEG1",       /* 1~5 */
+       "WMV", "DIVX", "XVID", "H261", "H262/MPEG2-part2",      /* 6~10 */
+       "H263v2", "H263v3", "Motion JPEG", "MPEG2", "MPEG4 part-2 Simple profile",      /* 11~15 */
+       "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 */
+       "MPEG4 part-10 (h.264)", "Real", "VC-1", "AVS", "Cinepak",      /* 21~25 */
+       "Indeo", "Theora", "Flv"        /* 26~28 */
 };
 
 
 
 FILE *fpFailList = NULL;
 
-static int mmfile_get_file_infomation (void *data, void* user_data, bool file_test);
+static int mmfile_get_file_infomation(void *data, void *user_data, bool file_test);
+static int mmfile_get_video_frame(void *data, void *accurate, bool file_test);
 
-inline static int mm_file_is_little_endian (void)
+static bool __read_file(const char *path, unsigned char **data, unsigned int *size)
 {
-    int i = 0x00000001;
-    return ((char *)&i)[0];
+       FILE *fp = NULL;
+       unsigned char *_data = NULL;
+       long _size = 0;
+
+       if (!path || !data || !size) {
+               printf("Invalid parameter\n");
+               return false;
+       }
+
+       fp = fopen(path, "r");
+       if (!fp) {
+               printf("fopen failed (%d)\n", errno);
+               return false;
+       }
+
+       if (fseek(fp, 0, SEEK_END) < 0) {
+               printf("fseek failed\n");
+               goto ERROR;
+       }
+
+       _size = ftell(fp);
+       if (_size <= 0) {
+               printf("ftell failed\n");
+               goto ERROR;
+       }
+
+       if (fseek(fp, 0, SEEK_SET) < 0) {
+               printf("fseek failed\n");
+               goto ERROR;
+       }
+
+       _data = calloc(1, _size);
+       if (!_data) {
+               printf("calloc failed\n");
+               goto ERROR;
+       }
+       if (fread(_data, sizeof(char), _size, fp) != (size_t)_size) {
+               printf("fread error\n");
+               goto ERROR;
+       }
+
+       fclose(fp);
+       *data = _data;
+       *size = (unsigned int)_size;
+       printf("file data = %p size = %u\n", *data, *size);
+
+       return true;
+
+ERROR:
+       SAFE_FREE(_data);
+       fclose(fp);
+
+       return false;
 }
 
-#define READ_FROM_FILE(FILE_PATH, data, size) \
-do{    \
-       FILE * fp = fopen (FILE_PATH, "r");     \
-       if (fp) {       \
-                       fseek (fp, 0, SEEK_END);        \
-                       size = ftell(fp);       \
-                       fseek (fp, 0, SEEK_SET);        \
-                       if(size > 0) data = malloc (size);      \
-                       if(data != NULL ) { if (fread (data, size, sizeof(char), fp) != size) { printf("fread error\n"); } }    \
-                       fclose (fp);    \
-                       printf("file size = %d\n", size );      \
-       }       \
-}while(0)
-
-static int
-_is_file_exist (const char *filename)
+static bool __is_file_exist(const char *filename)
 {
-       int ret = 1;
        if (filename) {
-               const char* to_access = (strstr(filename,"file://")!=NULL)? filename+7:filename;
-               ret = access (to_access, R_OK );
-               if (ret != 0) {
-                       printf  ("file [%s] not found.\n", to_access);
+               const char *to_access = (strstr(filename, "file://") != NULL) ? filename + 7 : filename;
+               if (access(to_access, R_OK) < 0) {
+                       printf("file [%s] not found.\n", to_access);
+                       return false;
                }
        }
-       return !ret;
+       return true;
 }
 
 
 int main(int argc, char **argv)
 {
-    struct stat statbuf;
-       bool file_test = true;          //if you want to test mm_file_create_content_XXX_from_memory() set file_test to false
-
-    if (_is_file_exist (argv[1])) {
-       int ret = lstat (argv[1], &statbuf);
-           if ( ret < 0 ) {
-               printf ("lstat error[%d]\n", ret);
-               return MMFILE_FAIL;
-       }
-
-               if (fpFailList == NULL) {
-                       fpFailList = fopen ("/opt/var/log/mmfile_fails.txt", "w");
-               }
+       struct stat statbuf;
+       bool file_test = true;          /*if you want to test mm_file_create_content_XXX_from_memory() set file_test to false */
 
-               if ( S_ISDIR (statbuf.st_mode) )        {
-                       mmfile_get_file_names (argv[1], mmfile_get_file_infomation, NULL);
-               } else {
-                       mmfile_get_file_infomation (argv[1], NULL, file_test);
+       if (__is_file_exist(argv[1])) {
+               int ret = lstat(argv[1], &statbuf);
+               if (ret < 0) {
+                       printf("lstat error[%d]\n", ret);
+                       return -1;
                }
 
+               if (fpFailList == NULL)
+                       fpFailList = fopen("/opt/var/log/mmfile_fails.txt", "w");
+
+               if (argv[2] == NULL)
+                       mmfile_get_file_infomation(argv[1], NULL, file_test);
+               else
+                       mmfile_get_video_frame(argv[1], argv[2], file_test);
+
                if (fpFailList != NULL) {
-                       fflush (fpFailList);
-                       fclose (fpFailList);
+                       fflush(fpFailList);
+                       fclose(fpFailList);
                }
-    }
+       }
 
-    return 0;//exit(0);
+       return 0;/*exit(0); */
 }
 
-static int mmfile_get_file_infomation (void *data, void* user_data, bool file_test)
+static int mmfile_get_file_infomation(void *data, void *user_data, bool file_test)
 {
        MMHandleType content_attrs = 0;
        MMHandleType tag_attrs = 0;
-       char *err_attr_name = NULL;
        int audio_track_num = 0;
        int video_track_num = 0;
        int ret = 0;
-       char filename[512];
+       char filename[512] = {0, };
 
-       memset (filename, 0x00, 512);
-       memcpy (filename, (char*)data, strlen ((char*)data));
+       memset(filename, 0x00, sizeof(filename));
+       SAFE_STRLCPY(filename, (char *)data, sizeof(filename));
 
-       MM_TIME_CHECK_START
+       MM_TIME_CHECK_START;
 
-       printf ("Extracting information for [%s] \n", filename);
+       printf("Extracting information for [%s] \n", filename);
        /* get track info */
        ret = mm_file_get_stream_info(filename, &audio_track_num, &video_track_num);
-       if (ret == MM_ERROR_NONE) {
-               printf ("# audio=%d, video=%d\n", audio_track_num, video_track_num);
+       if (ret == FILEINFO_ERROR_NONE) {
+               printf("# audio=%d, video=%d\n", audio_track_num, video_track_num);
        } else {
-               printf ("Failed to mm_file_get_stream_info() error=[%x]\n", ret);
+               printf("Failed to mm_file_get_stream_info() error=[%x]\n", ret);
        }
 
-       if(file_test) {
+       if (file_test) {
                /* get content handle */
                ret = mm_file_create_content_attrs(&content_attrs, filename);
        } else {
-               int file_size = 0;
-               unsigned char * buffer = NULL;
+               unsigned int file_size = 0;
+               unsigned char *buffer = NULL;
                /* Read file */
-               READ_FROM_FILE(filename, buffer, file_size);
+               if (!__read_file(filename, &buffer, &file_size)) {
+                       printf("Failed to __read_file()\n");
+
+                       MM_TIME_CHECK_STOP_BY_ERR;
+                       return -1;
+               }
 
-               ret =mm_file_create_content_attrs_from_memory(&content_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
+               ret = mm_file_create_content_attrs_from_memory(&content_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
+               SAFE_FREE(buffer);
        }
 
-       if (ret == MM_ERROR_NONE && content_attrs) {
+       if (ret == FILEINFO_ERROR_NONE && content_attrs) {
                ContentContext_t ccontent;
-               memset (&ccontent, 0, sizeof (ContentContext_t));
+               memset(&ccontent, 0, sizeof(ContentContext_t));
 
-               ret = mm_file_get_attrs(content_attrs, &err_attr_name, MM_FILE_CONTENT_DURATION, &ccontent.duration, NULL);
+               ret = mm_file_get_attrs(content_attrs, MM_FILE_CONTENT_DURATION, &ccontent.duration, NULL);
                printf("# duration: %d\n", ccontent.duration);
 
-               if (ret != MM_ERROR_NONE && err_attr_name)
-               {
-                       printf("failed to get %s\n", err_attr_name);
-                       free(err_attr_name);
-                       err_attr_name = NULL;
-               }
+               if (ret != FILEINFO_ERROR_NONE)
+                       printf("failed to get attrs\n");
 
-               if (audio_track_num)
-               {
+               if (audio_track_num) {
                        ret = mm_file_get_attrs(content_attrs,
-                                                                       NULL,
-                                                                       MM_FILE_CONTENT_AUDIO_CODEC, &ccontent.audio_codec,
-                                                                       MM_FILE_CONTENT_AUDIO_SAMPLERATE, &ccontent.audio_samplerate,
-                                                                       MM_FILE_CONTENT_AUDIO_BITRATE, &ccontent.audio_bitrate,
-                                                                       MM_FILE_CONTENT_AUDIO_CHANNELS, &ccontent.audio_channel,
-                                                                       MM_FILE_CONTENT_AUDIO_TRACK_INDEX, &ccontent.audio_track_id,
-                                                                       MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &ccontent.audio_track_num,
-                                                                       MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, &ccontent.audio_bitpersample,
-                                                                       NULL);
-
-                       if(ret != MM_ERROR_NONE) {
+                                                               MM_FILE_CONTENT_AUDIO_CODEC, &ccontent.audio_codec,
+                                                               MM_FILE_CONTENT_AUDIO_SAMPLERATE, &ccontent.audio_samplerate,
+                                                               MM_FILE_CONTENT_AUDIO_BITRATE, &ccontent.audio_bitrate,
+                                                               MM_FILE_CONTENT_AUDIO_CHANNELS, &ccontent.audio_channel,
+                                                               MM_FILE_CONTENT_AUDIO_TRACK_INDEX, &ccontent.audio_track_id,
+                                                               MM_FILE_CONTENT_AUDIO_TRACK_COUNT, &ccontent.audio_track_num,
+                                                               MM_FILE_CONTENT_AUDIO_BITPERSAMPLE, &ccontent.audio_bitpersample,
+                                                               NULL);
+
+                       if (ret != FILEINFO_ERROR_NONE) {
                                printf("failed to get audio attrs\n");
                        } else {
-                               printf ("[Audio] ----------------------------------------- \n");
+                               printf("[Audio] ----------------------------------------- \n");
                                printf("# audio codec: %d ", ccontent.audio_codec);
-                               printf ("[%s]\n", (ccontent.audio_codec >= 0 && ccontent.audio_codec < MM_AUDIO_CODEC_NUM)? AudioCodecTypeString[ccontent.audio_codec] : "Invalid");
+                               printf("[%s]\n", (ccontent.audio_codec >= 0 && ccontent.audio_codec < MM_AUDIO_CODEC_NUM) ? AudioCodecTypeString[ccontent.audio_codec] : "Invalid");
                                printf("# audio samplerate: %d Hz\n", ccontent.audio_samplerate);
                                printf("# audio bitrate: %d bps\n", ccontent.audio_bitrate);
                                printf("# audio channel: %d\n", ccontent.audio_channel);
@@ -275,26 +353,24 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                                printf("# audio bit per sample: %d\n", ccontent.audio_bitpersample);
                        }
                }
-       
-               if (video_track_num)
-               {
+
+               if (video_track_num) {
                        ret = mm_file_get_attrs(content_attrs,
-                                                                       NULL,
-                                                                       MM_FILE_CONTENT_VIDEO_CODEC, &ccontent.video_codec,
-                                                                       MM_FILE_CONTENT_VIDEO_BITRATE, &ccontent.video_bitrate,
-                                                                       MM_FILE_CONTENT_VIDEO_FPS, &ccontent.video_fps,
-                                                                       MM_FILE_CONTENT_VIDEO_TRACK_INDEX, &ccontent.video_track_id,
-                                                                       MM_FILE_CONTENT_VIDEO_WIDTH, &ccontent.video_w,
-                                                                       MM_FILE_CONTENT_VIDEO_HEIGHT, &ccontent.video_h,
-                                                                       MM_FILE_CONTENT_VIDEO_THUMBNAIL, &ccontent.thumbnail.value.p_val, &ccontent.thumbnail.len,
-                                                                       NULL);
-
-                       if(ret != MM_ERROR_NONE) {
+                                                               MM_FILE_CONTENT_VIDEO_CODEC, &ccontent.video_codec,
+                                                               MM_FILE_CONTENT_VIDEO_BITRATE, &ccontent.video_bitrate,
+                                                               MM_FILE_CONTENT_VIDEO_FPS, &ccontent.video_fps,
+                                                               MM_FILE_CONTENT_VIDEO_TRACK_INDEX, &ccontent.video_track_id,
+                                                               MM_FILE_CONTENT_VIDEO_WIDTH, &ccontent.video_w,
+                                                               MM_FILE_CONTENT_VIDEO_HEIGHT, &ccontent.video_h,
+                                                               MM_FILE_CONTENT_VIDEO_THUMBNAIL, &ccontent.thumbnail.value.p_val, &ccontent.thumbnail.len,
+                                                               NULL);
+
+                       if (ret != FILEINFO_ERROR_NONE) {
                                printf("failed to get video attrs\n");
                        } else {
-                               printf ("[Video] ----------------------------------------- \n");
+                               printf("[Video] ----------------------------------------- \n");
                                printf("# video codec: %d ", ccontent.video_codec);
-                               printf ("[%s]\n", (ccontent.video_codec >= 0 && ccontent.video_codec < MM_VIDEO_CODEC_NUM)? VideoCodecTypeString[ccontent.video_codec] : "Invalid");
+                               printf("[%s]\n", (ccontent.video_codec >= 0 && ccontent.video_codec < MM_VIDEO_CODEC_NUM) ? VideoCodecTypeString[ccontent.video_codec] : "Invalid");
                                printf("# video bitrate: %d bps\n", ccontent.video_bitrate);
                                printf("# video fps: %d\n", ccontent.video_fps);
                                printf("# video track id: %d\n", ccontent.video_track_id);
@@ -305,69 +381,100 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
 
                mm_file_destroy_content_attrs(content_attrs);
        } else {
-               printf ("Failed to mm_file_create_content_attrs() error=[%x]\n", ret);
+               printf("Failed to mm_file_create_content_attrs() error=[%x]\n", ret);
        }
 
-       if(file_test) {
+       if (file_test) {
                /* get tag handle */
                ret = mm_file_create_tag_attrs(&tag_attrs, filename);
        } else {
-               int file_size = 0;
-               unsigned char * buffer = NULL;
+               unsigned int file_size = 0;
+               unsigned char *buffer = NULL;
                /* Read file */
-               READ_FROM_FILE(filename, buffer, file_size);
+               if (!__read_file(filename, &buffer, &file_size)) {
+                       printf("Failed to __read_file()\n");
 
-               ret =mm_file_create_tag_attrs_from_memory(&tag_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
+                       MM_TIME_CHECK_STOP_BY_ERR;
+                       return -1;
+               }
+
+               ret = mm_file_create_tag_attrs_from_memory(&tag_attrs, buffer, file_size, MM_FILE_FORMAT_3GP);
+               SAFE_FREE(buffer);
        }
 
-       if (ret == MM_ERROR_NONE && tag_attrs) {
+       if (ret == FILEINFO_ERROR_NONE && tag_attrs) {
                TagContext_t ctag;
-               memset (&ctag, 0, sizeof (TagContext_t));
+               memset(&ctag, 0, sizeof(TagContext_t));
                /* get attributes of tag  */
-               ret = mm_file_get_attrs( tag_attrs,
-                                                                       &err_attr_name,
-                                                                       MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
-                                                                       MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
-                                                                       MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
-                                                                       MM_FILE_TAG_TITLE, &ctag.title.value.s_val, &ctag.title.len,
-                                                                       MM_FILE_TAG_GENRE, &ctag.genre.value.s_val, &ctag.genre.len,
-                                                                       MM_FILE_TAG_AUTHOR, &ctag.author.value.s_val, &ctag.author.len,
-                                                                       MM_FILE_TAG_COPYRIGHT, &ctag.copyright.value.s_val, &ctag.copyright.len,
-                                                                       MM_FILE_TAG_DATE, &ctag.date.value.s_val, &ctag.date.len,
-                                                                       MM_FILE_TAG_RECDATE, &ctag.recdate.value.s_val, &ctag.recdate.len,
-                                                                       MM_FILE_TAG_DESCRIPTION, &ctag.description.value.s_val, &ctag.description.len,
-                                                                       MM_FILE_TAG_COMMENT, &ctag.comment.value.s_val, &ctag.comment.len,
-                                                                       MM_FILE_TAG_ARTWORK, &ctag.artwork.value.p_val, &ctag.artwork.len,
-                                                                       MM_FILE_TAG_ARTWORK_SIZE, &ctag.artwork_size.value.i_val,
-                                                                       MM_FILE_TAG_ARTWORK_MIME, &ctag.artwork_mime.value.s_val, &ctag.artwork_mime.len,
-                                                                       MM_FILE_TAG_TRACK_NUM, &ctag.track_num.value.s_val, &ctag.track_num.len,
-                                                                       MM_FILE_TAG_CLASSIFICATION, &ctag.classfication.value.s_val, &ctag.classfication.len,
-                                                                       MM_FILE_TAG_RATING, &ctag.rating.value.s_val, &ctag.rating.len,
-                                                                       MM_FILE_TAG_LONGITUDE, &ctag.longitude.value.d_val,
-                                                                       MM_FILE_TAG_LATIDUE, &ctag.latitude.value.d_val,
-                                                                       MM_FILE_TAG_ALTIDUE, &ctag.altitude.value.d_val,
-                                                                       MM_FILE_TAG_CONDUCTOR, &ctag.conductor.value.s_val, &ctag.conductor.len,
-                                                                       MM_FILE_TAG_UNSYNCLYRICS, &ctag.unsynclyrics.value.s_val, &ctag.unsynclyrics.len,
-                                                                       MM_FILE_TAG_SYNCLYRICS_NUM, &ctag.synclyrics_size.value.i_val,
-                                                                       MM_FILE_TAG_ROTATE, &ctag.rotate.value.s_val, &ctag.rotate.len,
-                                                                       NULL);
-               if (ret != MM_ERROR_NONE &&  err_attr_name)
-               {
-                       printf("failed to get %s attrs\n", err_attr_name);
-                       free(err_attr_name);
-                       err_attr_name = NULL;
-
-                       if (msg_tmp_fp) /* opened by MM_TIME_CHECK_START */
-                       {
-                               fclose (msg_tmp_fp);
-                               msg_tmp_fp = NULL;
-                       }
+               ret = mm_file_get_attrs(tag_attrs,
+                                               MM_FILE_TAG_ARTIST, &ctag.artist.value.s_val, &ctag.artist.len,
+                                               MM_FILE_TAG_ALBUM, &ctag.album.value.s_val, &ctag.album.len,
+                                               MM_FILE_TAG_ALBUM_ARTIST, &ctag.album_artist.value.s_val, &ctag.album_artist.len,
+                                               MM_FILE_TAG_TITLE, &ctag.title.value.s_val, &ctag.title.len,
+                                               MM_FILE_TAG_GENRE, &ctag.genre.value.s_val, &ctag.genre.len,
+                                               MM_FILE_TAG_AUTHOR, &ctag.author.value.s_val, &ctag.author.len,
+                                               MM_FILE_TAG_COPYRIGHT, &ctag.copyright.value.s_val, &ctag.copyright.len,
+                                               MM_FILE_TAG_DATE, &ctag.date.value.s_val, &ctag.date.len,
+                                               MM_FILE_TAG_RECDATE, &ctag.recdate.value.s_val, &ctag.recdate.len,
+                                               MM_FILE_TAG_POS, &ctag.part_of_set.value.s_val, &ctag.part_of_set.len,
+                                               MM_FILE_TAG_DESCRIPTION, &ctag.description.value.s_val, &ctag.description.len,
+                                               MM_FILE_TAG_COMMENT, &ctag.comment.value.s_val, &ctag.comment.len,
+                                               MM_FILE_TAG_ARTWORK, &ctag.artwork.value.p_val, &ctag.artwork.len,
+                                               MM_FILE_TAG_ARTWORK_SIZE, &ctag.artwork_size.value.i_val,
+                                               MM_FILE_TAG_ARTWORK_MIME, &ctag.artwork_mime.value.s_val, &ctag.artwork_mime.len,
+                                               MM_FILE_TAG_TRACK_NUM, &ctag.track_num.value.s_val, &ctag.track_num.len,
+                                               MM_FILE_TAG_CLASSIFICATION, &ctag.classfication.value.s_val, &ctag.classfication.len,
+                                               MM_FILE_TAG_RATING, &ctag.rating.value.s_val, &ctag.rating.len,
+                                               MM_FILE_TAG_LONGITUDE, &ctag.longitude.value.d_val,
+                                               MM_FILE_TAG_LATIDUE, &ctag.latitude.value.d_val,
+                                               MM_FILE_TAG_ALTIDUE, &ctag.altitude.value.d_val,
+                                               MM_FILE_TAG_CONDUCTOR, &ctag.conductor.value.s_val, &ctag.conductor.len,
+                                               MM_FILE_TAG_UNSYNCLYRICS, &ctag.unsynclyrics.value.s_val, &ctag.unsynclyrics.len,
+                                               MM_FILE_TAG_SYNCLYRICS_NUM, &ctag.synclyrics_size.value.i_val,
+                                               MM_FILE_TAG_ROTATE, &ctag.rotate.value.s_val, &ctag.rotate.len,
+                                               MM_FILE_TAG_SPHERICAL, &ctag.is_spherical.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_STITCHED, &ctag.is_stitched.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_STITCHING_SOFTWARE, &ctag.stitching_software.value.s_val, &ctag.stitching_software.len,
+                                               MM_FILE_TAG_SPHERICAL_PROJECTION_TYPE, &ctag.projection_type.value.s_val, &ctag.projection_type.len,
+                                               MM_FILE_TAG_SPHERICAL_STEREO_MODE, &ctag.stereo_mode.value.s_val, &ctag.stereo_mode.len,
+                                               MM_FILE_TAG_SPHERICAL_SOURCE_COUNT, &ctag.source_count.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_INIT_VIEW_HEADING, &ctag.init_view_heading.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_INIT_VIEW_PITCH, &ctag.init_view_pitch.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_INIT_VIEW_ROLL, &ctag.init_view_roll.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_TIMESTAMP, &ctag.timestamp.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_FULL_PANO_WIDTH, &ctag.full_pano_width.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_FULL_PANO_HEIGHT, &ctag.full_pano_height.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_WIDTH, &ctag.cropped_area_image_width.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_CROPPED_AREA_IMAGE_HEIGHT, &ctag.cropped_area_image_height.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_CROPPED_AREA_LEFT, &ctag.cropped_area_left.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_CROPPED_AREA_TOP, &ctag.cropped_area_top.value.i_val,
+                                               MM_FILE_TAG_AMBISONIC_TYPE, &ctag.ambisonic_type.value.i_val,
+                                               MM_FILE_TAG_AMBISONIC_FORMAT, &ctag.ambisonic_format.value.i_val,
+                                               MM_FILE_TAG_AMBISONIC_ORDER, &ctag.ambisonic_order.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_STEREO_MODE, &ctag.stereo_mode_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_METADATA_SOURCE, &ctag.metadata_source_v2.value.s_val, &ctag.metadata_source_v2.len,
+                                               MM_FILE_TAG_SPHERICAL_V2_PROJ_TYPE, &ctag.proj_type_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_POSE_YAW, &ctag.pose_yaw_degrees_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_POSE_PITCH, &ctag.pose_pitch_degrees_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_POSE_ROLL, &ctag.pose_roll_degrees_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_CBMP_LAYOUT, &ctag.cbmp_layout_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_CBMP_PADDING, &ctag.cbmp_padding_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_TOP, &ctag.equi_projection_bounds_top_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_BOTTOM, &ctag.equi_projection_bounds_bottom_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_LEFT, &ctag.equi_projection_bounds_left_v2.value.i_val,
+                                               MM_FILE_TAG_SPHERICAL_V2_EQUI_BOUNDS_RIGHT, &ctag.equi_projection_bounds_right_v2.value.i_val,
+                                               MM_FILE_TAG_SMTA, &ctag.smta.value.i_val,
+                                               NULL);
+               if (ret != FILEINFO_ERROR_NONE) {
+                       printf("failed to get attrs\n");
+
+                       MM_TIME_CHECK_STOP_BY_ERR;
                        mm_file_destroy_tag_attrs(tag_attrs);
                        return -1;
                }
 
                /* print tag information         */
-               printf ("[Tag] =================================== \n");
+               printf("[Tag] =================================== \n");
                printf("# artist: [%s]\n", ctag.artist.value.s_val);
                printf("# title: [%s]\n", ctag.title.value.s_val);
                printf("# album: [%s]\n", ctag.album.value.s_val);
@@ -377,6 +484,7 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                printf("# copyright: [%s]\n", ctag.copyright.value.s_val);
                printf("# year: [%s]\n", ctag.date.value.s_val);
                printf("# recdate: [%s]\n", ctag.recdate.value.s_val);
+               printf("# part of a set: [%s]\n", ctag.part_of_set.value.s_val);
                printf("# description: [%s]\n", ctag.description.value.s_val);
                printf("# comment: [%s]\n", ctag.comment.value.s_val);
                printf("# artwork: [%p]\n", ctag.artwork.value.p_val);
@@ -393,17 +501,61 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                printf("# unsynclyrics: [%s]\n", ctag.unsynclyrics.value.s_val);
                printf("# synclyrics size: [%d]\n", ctag.synclyrics_size.value.i_val);
                printf("# rotate: [%s]\n", ctag.rotate.value.s_val);
+               printf("# is_spherical: [%d]\n", ctag.is_spherical.value.i_val);
+               printf("# is_stitched: [%d]\n", ctag.is_stitched.value.i_val);
+
+               if (ctag.is_spherical.value.i_val > 0 && ctag.is_stitched.value.i_val > 0) {
+                       printf("# stitching_software: [%s]\n", ctag.stitching_software.value.s_val);
+                       printf("# projection_type: [%s]\n", ctag.projection_type.value.s_val);
+                       printf("# stereo_mode [%s]\n", ctag.stereo_mode.value.s_val);
+                       printf("# source_count: [%d]\n", ctag.source_count.value.i_val);
+                       printf("# init_view_heading: [%d]\n", ctag.init_view_heading.value.i_val);
+                       printf("# init_view_pitch: [%d]\n", ctag.init_view_pitch.value.i_val);
+                       printf("# init_view_roll: [%d]\n", ctag.init_view_roll.value.i_val);
+                       printf("# time_stamp: [%d]\n", ctag.timestamp.value.i_val);
+                       printf("# full_pano_width: [%d]\n", ctag.full_pano_width.value.i_val);
+                       printf("# full_pano_height: [%d]\n", ctag.full_pano_height.value.i_val);
+                       printf("# cropped_area_image_width: [%d]\n", ctag.cropped_area_image_width.value.i_val);
+                       printf("# cropped_area_image_height: [%d]\n", ctag.cropped_area_image_height.value.i_val);
+                       printf("# cropped_area_left: [%d]\n", ctag.cropped_area_left.value.i_val);
+                       printf("# cropped_area_top: [%d]\n", ctag.cropped_area_top.value.i_val);
+               }
+
+               printf("# ambisonic_type: [%d]\n", ctag.ambisonic_type.value.i_val);
+
+               if (ctag.ambisonic_type.value.i_val > 0) {
+                       printf("# ambisonic_format: [%d]\n", ctag.ambisonic_format.value.i_val);
+                       printf("# ambisonic_order: [%d]\n", ctag.ambisonic_order.value.i_val);
+               }
 
-               if(ctag.synclyrics_size.value.i_val > 0) {
+               printf("# stereo_mode_v2: [%d]\n", ctag.stereo_mode_v2.value.i_val);
+
+               if (ctag.proj_type_v2.value.i_val >= 0) {
+                       printf("# proj_type_v2: [%d]\n", ctag.proj_type_v2.value.i_val);
+                       printf("# metadata_source_v2: [%s]\n", ctag.metadata_source_v2.value.s_val);
+                       printf("# pose_yaw_degrees_v2: [%d]\n", ctag.pose_yaw_degrees_v2.value.i_val);
+                       printf("# pose_pitch_degrees_v2: [%d]\n", ctag.pose_pitch_degrees_v2.value.i_val);
+                       printf("# pose_roll_degrees_v2: [%d]\n", ctag.pose_roll_degrees_v2.value.i_val);
+                       printf("# cbmp_layout_v2: [%d]\n", ctag.cbmp_layout_v2.value.i_val);
+                       printf("# cbmp_padding_v2: [%d]\n", ctag.cbmp_padding_v2.value.i_val);
+                       printf("# equi_projection_bounds_top_v2: [%d]\n", ctag.equi_projection_bounds_top_v2.value.i_val);
+                       printf("# equi_projection_bounds_bottom_v2: [%d]\n", ctag.equi_projection_bounds_bottom_v2.value.i_val);
+                       printf("# equi_projection_bounds_left_v2: [%d]\n", ctag.equi_projection_bounds_left_v2.value.i_val);
+                       printf("# equi_projection_bounds_right_v2: [%d]\n", ctag.equi_projection_bounds_right_v2.value.i_val);
+               }
+
+               printf("# smta: [%d]\n", ctag.smta.value.i_val);
+
+               if (ctag.synclyrics_size.value.i_val > 0) {
                        int idx = 0;
                        unsigned long time_info = 0;
-                       char * lyrics_info = NULL;
+                       char *lyrics_info = NULL;
 
                        printf("# synclyrics: \n");
-                       
-                       for(idx = 0; idx < ctag.synclyrics_size.value.i_val; idx++) {
+
+                       for (idx = 0; idx < ctag.synclyrics_size.value.i_val; idx++) {
                                ret = mm_file_get_synclyrics_info(tag_attrs, idx, &time_info, &lyrics_info);
-                               if(ret == MM_ERROR_NONE) {
+                               if (ret == FILEINFO_ERROR_NONE) {
                                        printf("[%2d][%6ld][%s]\n", idx, time_info, lyrics_info);
                                } else {
                                        printf("Error when get lyrics\n");
@@ -411,25 +563,70 @@ static int mmfile_get_file_infomation (void *data, void* user_data, bool file_te
                                }
                        }
                }
-               
+
                /* release tag */
                ret = mm_file_destroy_tag_attrs(tag_attrs);
-               if (ret != MM_ERROR_NONE) {
+               if (ret != FILEINFO_ERROR_NONE) {
                        printf("Error mm_file_destroy_tag_attrs: %d", ret);
-                       if (msg_tmp_fp) {
-                               fclose (msg_tmp_fp);
-                               msg_tmp_fp = NULL;
-                       }
+                       MM_TIME_CHECK_STOP_BY_ERR;
                        return -1;
                }
        } else {
-               printf ("Failed to mm_file_create_tag_attrs() error=[%x]\n", ret);
+               printf("Failed to mm_file_create_tag_attrs() error=[%x]\n", ret);
        }
 
 
-       printf ("=================================================\n\n");
+       printf("=================================================\n\n");
+
+       MM_TIME_CHECK_FINISH(filename);
+
+       return 0;
+}
+
+static int mmfile_get_video_frame(void *data, void *accurate, bool file_test)
+{
+       int ret = 0;
+       char filename[512] = {0, };
+       char accurate_mode[10] = {0, };
+       void *_frame = NULL;
+       int _frame_size = 0;
+       int width = 0;
+       int height = 0;
+       bool is_accurate = FALSE;
+       unsigned long long time_stamp = 5 * 1000 * 1000;                //5sec
+
+       memset(filename, 0x00, sizeof(filename));
+       SAFE_STRLCPY(filename, (char *)data, sizeof(filename));
+
+       memset(accurate_mode, 0x00, sizeof(accurate_mode));
+       SAFE_STRLCPY(accurate_mode, (char *)accurate, sizeof(accurate_mode));
+
+       if (strlen(accurate_mode) > 0) {
+               if (strncmp(accurate_mode, "1", 1) == 0)
+                       is_accurate = TRUE;
+       }
+
+       printf("Extracting video frame for [%s] [%llu] accurate [%d]\n", filename, time_stamp, is_accurate);
+
+       if (file_test == TRUE)
+               ret = mm_file_get_video_frame(filename, time_stamp, is_accurate, (unsigned char **)&_frame, &_frame_size, &width, &height);
+       else    {
+               unsigned int file_size = 0;
+               unsigned char *buffer = NULL;
+               /* Read file */
+               if (!__read_file(filename, &buffer, &file_size)) {
+                       printf("Failed to __read_file()\n");
+                       return -1;
+               }
+
+               ret = mm_file_get_video_frame_from_memory(buffer, file_size, time_stamp, is_accurate, (unsigned char **)&_frame, &_frame_size, &width, &height);
+               SAFE_FREE(buffer);
+       }
 
-       MM_TIME_CHECK_FINISH (filename);
+       if (ret != FILEINFO_ERROR_NONE)
+               printf("Failed to mm_file_get_video_frame() error=[%x]\n", ret);
+       else
+               printf("video_frame[%p], video_frame_len = [%d] width = [%d] height = [%d]\n", _frame, _frame_size, width, height);
 
-    return 0;
+       return 0;
 }