Browse code

lavf: export id3v2 attached pictures as streams.

Anton Khirnov authored on 2012/02/25 17:53:35
Showing 3 changed files
... ...
@@ -702,3 +702,37 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
702 702
         current = next;
703 703
     }
704 704
 }
705
+
706
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
707
+{
708
+    ID3v2ExtraMeta *cur;
709
+
710
+    for (cur = *extra_meta; cur; cur = cur->next) {
711
+        ID3v2ExtraMetaAPIC *apic;
712
+        AVStream *st;
713
+
714
+        if (strcmp(cur->tag, "APIC"))
715
+            continue;
716
+        apic = cur->data;
717
+
718
+        if (!(st = avformat_new_stream(s, NULL)))
719
+            return AVERROR(ENOMEM);
720
+
721
+        st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
722
+        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
723
+        st->codec->codec_id   = apic->id;
724
+        av_dict_set(&st->metadata, "title",   apic->description, 0);
725
+        av_dict_set(&st->metadata, "comment", apic->type, 0);
726
+
727
+        av_init_packet(&st->attached_pic);
728
+        st->attached_pic.data         = apic->data;
729
+        st->attached_pic.size         = apic->len;
730
+        st->attached_pic.destruct     = av_destruct_packet;
731
+        st->attached_pic.stream_index = st->index;
732
+
733
+        apic->data = NULL;
734
+        apic->len  = 0;
735
+    }
736
+
737
+    return 0;
738
+}
... ...
@@ -109,6 +109,12 @@ int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version, const char *mag
109 109
  */
110 110
 void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
111 111
 
112
+/**
113
+ * Create a stream for each APIC (attached picture) extracted from the
114
+ * ID3v2 header.
115
+ */
116
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta);
117
+
112 118
 extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
113 119
 extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
114 120
 
... ...
@@ -520,6 +520,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
520 520
     AVFormatContext *s = *ps;
521 521
     int i, ret = 0;
522 522
     AVDictionary *tmp = NULL;
523
+    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
523 524
 
524 525
     if (!s && !(s = avformat_alloc_context()))
525 526
         return AVERROR(ENOMEM);
... ...
@@ -562,12 +563,17 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
562 562
 
563 563
     /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
564 564
     if (s->pb)
565
-        ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
565
+        ff_id3v2_read_all(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
566 566
 
567 567
     if (s->iformat->read_header)
568 568
         if ((ret = s->iformat->read_header(s)) < 0)
569 569
             goto fail;
570 570
 
571
+    if (id3v2_extra_meta &&
572
+        (ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
573
+        goto fail;
574
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
575
+
571 576
     /* queue attached pictures */
572 577
     for (i = 0; i < s->nb_streams; i++)
573 578
         if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
... ...
@@ -589,6 +595,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
589 589
     return 0;
590 590
 
591 591
 fail:
592
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
592 593
     av_dict_free(&tmp);
593 594
     if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
594 595
         avio_close(s->pb);