diff options
author | Anton Khirnov <anton@khirnov.net> | 2012-02-25 09:53:35 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2012-02-29 14:16:32 +0100 |
commit | 079ea6ca5f8f108ec328d3c2c1792e676fc30b9c (patch) | |
tree | 15d38cabd66e3c5219fd66badb9410447c049683 | |
parent | dd2a4bcfd72eee85710142943a1c68ac02520771 (diff) | |
download | ffmpeg-079ea6ca5f8f108ec328d3c2c1792e676fc30b9c.tar.gz |
lavf: export id3v2 attached pictures as streams.
-rw-r--r-- | libavformat/id3v2.c | 34 | ||||
-rw-r--r-- | libavformat/id3v2.h | 6 | ||||
-rw-r--r-- | libavformat/utils.c | 9 |
3 files changed, 48 insertions, 1 deletions
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 853a04c78e..4170c853a6 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 f358d02892..c3f08f5875 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 c8dd7f5868..e657362a38 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); |