[FFmpeg-cvslog] lavf: export id3v2 attached pictures as streams.

Anton Khirnov git at videolan.org
Thu Mar 1 03:20:19 CET 2012


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Sat Feb 25 09:53:35 2012 +0100| [079ea6ca5f8f108ec328d3c2c1792e676fc30b9c] | committer: Anton Khirnov

lavf: export id3v2 attached pictures as streams.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=079ea6ca5f8f108ec328d3c2c1792e676fc30b9c
---

 libavformat/id3v2.c |   34 ++++++++++++++++++++++++++++++++++
 libavformat/id3v2.h |    6 ++++++
 libavformat/utils.c |    9 ++++++++-
 3 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 853a04c..4170c85 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -702,3 +702,37 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
         current = next;
     }
 }
+
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
+{
+    ID3v2ExtraMeta *cur;
+
+    for (cur = *extra_meta; cur; cur = cur->next) {
+        ID3v2ExtraMetaAPIC *apic;
+        AVStream *st;
+
+        if (strcmp(cur->tag, "APIC"))
+            continue;
+        apic = cur->data;
+
+        if (!(st = avformat_new_stream(s, NULL)))
+            return AVERROR(ENOMEM);
+
+        st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
+        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+        st->codec->codec_id   = apic->id;
+        av_dict_set(&st->metadata, "title",   apic->description, 0);
+        av_dict_set(&st->metadata, "comment", apic->type, 0);
+
+        av_init_packet(&st->attached_pic);
+        st->attached_pic.data         = apic->data;
+        st->attached_pic.size         = apic->len;
+        st->attached_pic.destruct     = av_destruct_packet;
+        st->attached_pic.stream_index = st->index;
+
+        apic->data = NULL;
+        apic->len  = 0;
+    }
+
+    return 0;
+}
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index f358d02..c3f08f5 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -109,6 +109,12 @@ int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version, const char *mag
  */
 void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
 
+/**
+ * Create a stream for each APIC (attached picture) extracted from the
+ * ID3v2 header.
+ */
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta);
+
 extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
 extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index c8dd7f5..e657362 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -520,6 +520,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
     AVFormatContext *s = *ps;
     int i, ret = 0;
     AVDictionary *tmp = NULL;
+    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
 
     if (!s && !(s = avformat_alloc_context()))
         return AVERROR(ENOMEM);
@@ -562,12 +563,17 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
 
     /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
     if (s->pb)
-        ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
+        ff_id3v2_read_all(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
 
     if (s->iformat->read_header)
         if ((ret = s->iformat->read_header(s)) < 0)
             goto fail;
 
+    if (id3v2_extra_meta &&
+        (ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
+        goto fail;
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+
     /* queue attached pictures */
     for (i = 0; i < s->nb_streams; i++)
         if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
@@ -589,6 +595,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
     return 0;
 
 fail:
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
     av_dict_free(&tmp);
     if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
         avio_close(s->pb);



More information about the ffmpeg-cvslog mailing list