Improve 'mmfile_format_read_tag_ffmpg' function 09/212809/4
authorjiyong.min <jiyong.min@samsung.com>
Tue, 27 Aug 2019 02:08:10 +0000 (11:08 +0900)
committerjiyong.min <jiyong.min@samsung.com>
Tue, 27 Aug 2019 05:18:05 +0000 (14:18 +0900)
Change-Id: I2edf99b08d29631d0363e1ce3493004ad99bfa21

formats/ffmpeg/mm_file_format_ffmpeg.c
utils/include/mm_file_utils.h

index 9ad513c..e7c5bf7 100755 (executable)
@@ -546,6 +546,150 @@ exception:
 #define POS_OF_MIME_LEN DATA_LENGTH
 #define CONVERT_TO_INT(dest, src) {dest = 0; dest |= (0 | src[0] << 24) | (0 | src[1] << 16) | (0 | src[2] << 8) | (0 | src[3]); }
 
+static void __fill_picture_in_context(char *value, MMFileFormatContext *formatContext)
+{
+       gsize len = 0;
+       guchar *meta_data = NULL;
+
+       meta_data = g_base64_decode(value, &len);
+       if (!meta_data) {
+               debug_log(RELEASE, "no picture");
+               return;
+       }
+
+       /* in METADATA_BLOCK_PICTURE,
+       the length of mime type and  the length of description are flexible,
+       so, we have to get the length of their for getting correct postion of picture data. */
+       int mime_len = 0;
+       int description_len = 0;
+       int data_len = 0;
+       int current_pos = 0;
+       unsigned char current_data[DATA_LENGTH] = {0};
+
+       /* get length of mime_type */
+       memcpy(current_data, meta_data + POS_OF_MIME_LEN, DATA_LENGTH);
+       CONVERT_TO_INT(mime_len, current_data);
+
+       /* get length of description */
+       current_pos =  mime_len + (DATA_LENGTH * 2); /*current position is length of description */
+       memcpy(current_data, meta_data + current_pos, DATA_LENGTH);
+       CONVERT_TO_INT(description_len, current_data);
+
+       /* get length of picture data */
+       current_pos = mime_len  + description_len + (DATA_LENGTH * 7); /*current position is length of picture data */
+       memcpy(current_data, meta_data + current_pos, DATA_LENGTH);
+       CONVERT_TO_INT(data_len, current_data);
+
+       /* set the size of art work */
+       formatContext->artworkSize = data_len;
+
+       /* set mime type */
+       current_pos = POS_OF_MIME_LEN + DATA_LENGTH; /*current position is mime type */
+       mmfile_free(formatContext->artworkMime);
+       formatContext->artworkMime = strndup((const char *)meta_data + current_pos, mime_len);
+
+       /* set art work data */
+       current_pos = mime_len  + description_len + (DATA_LENGTH * 8); /*current position is picture data */
+       mmfile_free(formatContext->artwork);
+
+       formatContext->artwork = mmfile_malloc(data_len);
+       if (formatContext->artwork)
+               memcpy(formatContext->artwork, meta_data + current_pos, data_len);
+
+       g_free(meta_data);
+}
+
+static void __fill_artwork_in_context(AVStream *st, MMFileFormatContext *formatContext)
+{
+       AVPacket pkt = st->attached_pic;
+       int codec_id = st->codecpar->codec_id;
+
+       if (!pkt.data || pkt.size <= 0) {
+               return;
+       }
+
+       /*Set mime type*/
+       mmfile_free(formatContext->artworkMime);
+
+       if (codec_id == AV_CODEC_ID_MJPEG)
+               formatContext->artworkMime = mmfile_strdup("image/jpeg");
+       else if (codec_id == AV_CODEC_ID_PNG)
+               formatContext->artworkMime = mmfile_strdup("image/png");
+       else if (codec_id == AV_CODEC_ID_BMP)
+               formatContext->artworkMime = mmfile_strdup("image/bmp");
+       else
+               debug_error(DEBUG, "Unknown cover type: 0x%x\n", codec_id);
+
+       /*Copy artwork*/
+       mmfile_free(formatContext->artwork);
+
+       formatContext->artworkSize = pkt.size;
+       formatContext->artwork = mmfile_malloc(pkt.size);
+       if (formatContext->artwork)
+               memcpy(formatContext->artwork, pkt.data, pkt.size);
+}
+
+static void __fill_metainfo_in_context(AVDictionary *metainfo, MMFileFormatContext *formatContext)
+{
+       AVDictionaryEntry *tag = NULL;
+
+       while ((tag = av_dict_get(metainfo, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+               if (!tag->key) {
+                       continue;
+               }
+
+               if (!g_ascii_strcasecmp(tag->key, "title")) {
+                       MMFILE_SAFE_FREE(formatContext->title);
+                       formatContext->title = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "artist")) {
+                       MMFILE_SAFE_FREE(formatContext->artist);
+                       formatContext->artist = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "composer")) {
+                       MMFILE_SAFE_FREE(formatContext->composer);
+                       formatContext->composer = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "album")) {
+                       MMFILE_SAFE_FREE(formatContext->album);
+                       formatContext->album = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "album_artist")) {
+                       MMFILE_SAFE_FREE(formatContext->album_artist);
+                       formatContext->album_artist = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "copyright")) {
+                       MMFILE_SAFE_FREE(formatContext->copyright);
+                       formatContext->copyright = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "comment")) {
+                       MMFILE_SAFE_FREE(formatContext->comment);
+                       formatContext->comment = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "description")) {
+                       MMFILE_SAFE_FREE(formatContext->description);
+                       formatContext->description = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "genre")) {
+                       MMFILE_SAFE_FREE(formatContext->genre);
+                       formatContext->genre = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "date")) {
+                       MMFILE_SAFE_FREE(formatContext->year);
+                       formatContext->year = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "creation_time")) {
+                       MMFILE_SAFE_FREE(formatContext->recDate);
+                       formatContext->recDate = mmfile_strdup(tag->value);
+               } else if ((!g_ascii_strcasecmp(tag->key, "track")) || (!g_ascii_strcasecmp(tag->key, "tracknumber"))) {
+                       MMFILE_SAFE_FREE(formatContext->tagTrackNum);
+                       formatContext->tagTrackNum = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "lyrics")) {
+                       MMFILE_SAFE_FREE(formatContext->unsyncLyrics);
+                       formatContext->unsyncLyrics = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "rotate")) {   /*can be "90", "180", "270" */
+                       MMFILE_SAFE_FREE(formatContext->rotate);
+                       formatContext->rotate = mmfile_strdup(tag->value);
+               } else if (!g_ascii_strcasecmp(tag->key, "spherical-video")) {
+                       ParseSpatialVideoMetadataFromXMLString(tag->value, formatContext);
+               } else if (!g_ascii_strcasecmp(tag->key, "metadata_block_picture")) {
+                       __fill_picture_in_context(tag->value, formatContext);
+               } else {
+                       debug_log(RELEASE, "Not support metadata. [%s:%s]", tag->key, tag->value);
+               }
+       }
+}
+
 EXPORT_API
 int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext)
 {
@@ -557,6 +701,10 @@ int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext)
        }
 
        pFormatCtx = formatContext->privateFormatData;
+       if (!pFormatCtx) {
+               debug_warning(DEBUG, "No format information");
+               return MMFILE_FORMAT_SUCCESS;
+       }
 
        if (formatContext->formatType == MM_FILE_FORMAT_3GP || formatContext->formatType == MM_FILE_FORMAT_MP4) {
                MMFileUtilGetMetaDataFromMP4(formatContext);
@@ -569,156 +717,35 @@ int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext)
        /*metadata extracted by ffmpeg*/
        unsigned int idx = 0;
 
-       if (pFormatCtx != NULL) {
-               for (idx = 0; idx < pFormatCtx->nb_streams + 1; idx++) {
-                       AVDictionary *metainfo = NULL;
-                       AVStream *st = NULL;
-
-                       if (idx < pFormatCtx->nb_streams) {     /*Check metadata of normal stream like audio, video, video cover art(cover art saved in new stream). refer to mov_read_covr() in ffmpeg. */
-                               st = pFormatCtx->streams[idx];
-                               if (st != NULL)
-                                       metainfo = st->metadata;
-                       } else {        /*Check metadata of Content */
-                               if (pFormatCtx->metadata != NULL) {
-                                       metainfo = pFormatCtx->metadata;
-                               } else {
-                                       continue;
-                               }
+       for (idx = 0; idx < pFormatCtx->nb_streams + 1; idx++) {
+               AVDictionary *metainfo = NULL;
+               AVStream *st = NULL;
+
+               /* Check metadata of normal stream like audio, video, video cover art
+                * (cover art saved in new stream). refer to mov_read_covr() in ffmpeg.
+                */
+               if (idx < pFormatCtx->nb_streams) {
+                       st = pFormatCtx->streams[idx];
+                       if (st != NULL)
+                               metainfo = st->metadata;
+               } else {        /*Check metadata of Content */
+                       if (pFormatCtx->metadata != NULL) {
+                               metainfo = pFormatCtx->metadata;
+                       } else {
+                               continue;
                        }
+               }
 
-                       /*refer to mov_read_covr() in ffmpeg.*/
-                       if (st != NULL) {
-                               AVPacket pkt = st->attached_pic;
-                               int codec_id = st->codecpar->codec_id;
-
-                               if ((pkt.data != NULL) && (pkt.size > 0)) {
-                                       /*Set mime type*/
-                                       mmfile_free(formatContext->artworkMime);
-
-                                       if (codec_id == AV_CODEC_ID_MJPEG)
-                                               formatContext->artworkMime = mmfile_strdup("image/jpeg");
-                                       else if (codec_id == AV_CODEC_ID_PNG)
-                                               formatContext->artworkMime = mmfile_strdup("image/png");
-                                       else if (codec_id == AV_CODEC_ID_BMP)
-                                               formatContext->artworkMime = mmfile_strdup("image/bmp");
-                                       else
-                                               debug_error(DEBUG, "Unknown cover type: 0x%x\n", codec_id);
-
-                                       /*Copy artwork*/
-                                       mmfile_free(formatContext->artwork);
+               /*refer to mov_read_covr() in ffmpeg.*/
+               if (st)
+                       __fill_artwork_in_context(st, formatContext);
 
-                                       formatContext->artworkSize = pkt.size;
-                                       formatContext->artwork = mmfile_malloc(pkt.size);
-                                       if (formatContext->artwork != NULL)
-                                               memcpy(formatContext->artwork, pkt.data, pkt.size);
-                               }
-                       }
+               if (metainfo)
+                       __fill_metainfo_in_context(metainfo, formatContext);
 
-                       if (metainfo != NULL) {
-                               AVDictionaryEntry *tag = NULL;
-                               while ((tag = av_dict_get(metainfo, "", tag, AV_DICT_IGNORE_SUFFIX))) {
-                                       if (tag->key != NULL) {
-                                               if (!g_ascii_strcasecmp(tag->key, "title")) {
-                                                       if (formatContext->title)       free(formatContext->title);
-                                                       formatContext->title = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "artist")) {
-                                                       if (formatContext->artist)      free(formatContext->artist);
-                                                       formatContext->artist = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "composer")) {
-                                                       if (formatContext->composer)    free(formatContext->composer);
-                                                       formatContext->composer = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "album")) {
-                                                       if (formatContext->album)       free(formatContext->album);
-                                                       formatContext->album = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "album_artist")) {
-                                                       if (formatContext->album_artist)        free(formatContext->album_artist);
-                                                       formatContext->album_artist = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "copyright")) {
-                                                       if (formatContext->copyright)   free(formatContext->copyright);
-                                                       formatContext->copyright = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "comment")) {
-                                                       if (formatContext->comment)     free(formatContext->comment);
-                                                       formatContext->comment = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "description")) {
-                                                       if (formatContext->description) free(formatContext->description);
-                                                       formatContext->description = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "genre")) {
-                                                       if (formatContext->genre)       free(formatContext->genre);
-                                                       formatContext->genre = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "date")) {
-                                                       if (formatContext->year)        free(formatContext->year);
-                                                       formatContext->year = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "creation_time")) {
-                                                       if (formatContext->recDate)     free(formatContext->recDate);
-                                                       formatContext->recDate = mmfile_strdup(tag->value);
-                                               } else if ((!g_ascii_strcasecmp(tag->key, "track")) || (!g_ascii_strcasecmp(tag->key, "tracknumber"))) {
-                                                       if (formatContext->tagTrackNum) free(formatContext->tagTrackNum);
-                                                       formatContext->tagTrackNum = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "lyrics")) {
-                                                       if (formatContext->unsyncLyrics)        free(formatContext->unsyncLyrics);
-                                                       formatContext->unsyncLyrics = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "rotate")) {   /*can be "90", "180", "270" */
-                                                       if (formatContext->rotate)      free(formatContext->rotate);
-                                                       formatContext->rotate = mmfile_strdup(tag->value);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "spherical-video")) {
-                                                       ParseSpatialVideoMetadataFromXMLString(tag->value, formatContext);
-                                               } else if (!g_ascii_strcasecmp(tag->key, "metadata_block_picture")) {
-                                                       gsize len = 0;
-                                                       guchar *meta_data = NULL;
-
-                                                       meta_data = g_base64_decode(tag->value, &len);
-                                                       if (meta_data != NULL) {
-                                                               /* in METADATA_BLOCK_PICTURE,
-                                                               the length of mime type and  the length of description are flexible,
-                                                               so, we have to get the length of their for getting correct postion of picture data. */
-                                                               int mime_len = 0;
-                                                               int description_len = 0;
-                                                               int data_len = 0;
-                                                               int current_pos = 0;
-                                                               unsigned char current_data[DATA_LENGTH] = {0};
-
-                                                               /* get length of mime_type */
-                                                               memcpy(current_data, meta_data + POS_OF_MIME_LEN, DATA_LENGTH);
-                                                               CONVERT_TO_INT(mime_len, current_data);
-
-                                                               /* get length of description */
-                                                               current_pos =  mime_len + (DATA_LENGTH * 2); /*current position is length of description */
-                                                               memcpy(current_data, meta_data + current_pos, DATA_LENGTH);
-                                                               CONVERT_TO_INT(description_len, current_data);
-
-                                                               /* get length of picture data */
-                                                               current_pos = mime_len  + description_len + (DATA_LENGTH * 7); /*current position is length of picture data */
-                                                               memcpy(current_data, meta_data + current_pos, DATA_LENGTH);
-                                                               CONVERT_TO_INT(data_len, current_data);
-
-                                                               /* set the size of art work */
-                                                               formatContext->artworkSize = data_len;
-
-                                                               /* set mime type */
-                                                               current_pos = POS_OF_MIME_LEN + DATA_LENGTH; /*current position is mime type */
-                                                               mmfile_free(formatContext->artworkMime);
-                                                               formatContext->artworkMime = strndup((const char *)meta_data + current_pos, mime_len);
-
-                                                               /* set art work data */
-                                                               current_pos = mime_len  + description_len + (DATA_LENGTH * 8); /*current position is picture data */
-                                                               mmfile_free(formatContext->artwork);
-
-                                                               formatContext->artwork = mmfile_malloc(data_len);
-                                                               if (formatContext->artwork != NULL)
-                                                                       memcpy(formatContext->artwork, meta_data + current_pos, data_len);
-
-                                                               g_free(meta_data);
-                                                       }
-                                               } else {
-                                                       debug_log(RELEASE, "Not support metadata. [%s:%s]", tag->key, tag->value);
-                                               }
-                                       }
-                               }
-                       }
 #ifdef __MMFILE_TEST_MODE__
-                       mmfile_format_print_tags(formatContext);
+               mmfile_format_print_tags(formatContext);
 #endif
-               }
        }
 
        return MMFILE_FORMAT_SUCCESS;
index ec10dab..6d9679e 100755 (executable)
@@ -46,6 +46,8 @@ extern "C" {
 #define MMFILE_IO_SUCCESS              MMFILE_UTIL_SUCCESS
 #define CAST_MM_HANDLE(x)                      (MMHandleType)(x)
 
+#define MMFILE_SAFE_FREE(src)  {if (src) {free(src); src = NULL; } }
+
 #ifndef TRUE
 #define TRUE   (1 == 1)
 #endif