diff options
author | Richard Shaffer <rshaffer@tunein.com> | 2018-02-01 18:37:45 -0800 |
---|---|---|
committer | wm4 <nfxjfg@googlemail.com> | 2018-02-12 22:08:49 +0100 |
commit | e023334661e6eafcf638ffc2a780fd495fc25ec9 (patch) | |
tree | 0735f5382a05a8f60d06aefd48d324fafabeb9dd | |
parent | 192ea5bb77a7ca0b28c41f21ae6dc779dedca9da (diff) | |
download | ffmpeg-e023334661e6eafcf638ffc2a780fd495fc25ec9.tar.gz |
libavformat/aac: Parse ID3 tags between ADTS frames.
While rare, ID3 tags may be inserted between ADTS frames. This change enables
parsing them and setting the appropriate metadata updated event flag.
-rw-r--r-- | libavformat/aacdec.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c index 36d558ff54..5ec706bdc7 100644 --- a/libavformat/aacdec.c +++ b/libavformat/aacdec.c @@ -22,8 +22,10 @@ #include "libavutil/intreadwrite.h" #include "avformat.h" +#include "avio_internal.h" #include "internal.h" #include "id3v1.h" +#include "id3v2.h" #include "apetag.h" #define ADTS_HEADER_SIZE 7 @@ -116,13 +118,52 @@ static int adts_aac_read_header(AVFormatContext *s) return 0; } +static int handle_id3(AVFormatContext *s, AVPacket *pkt) +{ + AVDictionary *metadata = NULL; + AVIOContext ioctx; + ID3v2ExtraMeta *id3v2_extra_meta = NULL; + int ret; + + ret = av_append_packet(s->pb, pkt, ff_id3v2_tag_len(pkt->data) - pkt->size); + if (ret < 0) { + av_packet_unref(pkt); + return ret; + } + + ffio_init_context(&ioctx, pkt->data, pkt->size, 0, NULL, NULL, NULL, NULL); + ff_id3v2_read_dict(&ioctx, &metadata, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + if ((ret = ff_id3v2_parse_priv_dict(&metadata, &id3v2_extra_meta)) < 0) + goto error; + + if (metadata) { + if ((ret = av_dict_copy(&s->metadata, metadata, 0)) < 0) + goto error; + s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; + } + +error: + av_packet_unref(pkt); + ff_id3v2_free_extra_meta(&id3v2_extra_meta); + av_dict_free(&metadata); + + return ret; +} + static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, fsize; - ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE); + ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE)); + + if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) { + if ((ret = handle_id3(s, pkt)) >= 0) + ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE); + } + if (ret < 0) return ret; + if (ret < ADTS_HEADER_SIZE) { av_packet_unref(pkt); return AVERROR(EIO); @@ -139,7 +180,7 @@ static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_INVALIDDATA; } - ret = av_append_packet(s->pb, pkt, fsize - ADTS_HEADER_SIZE); + ret = av_append_packet(s->pb, pkt, fsize - pkt->size); if (ret < 0) av_packet_unref(pkt); |