#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)
{
}
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);
/*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;