aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Shaffer <rshaffer@tunein.com>2018-02-01 18:37:45 -0800
committerwm4 <nfxjfg@googlemail.com>2018-02-12 22:08:49 +0100
commite023334661e6eafcf638ffc2a780fd495fc25ec9 (patch)
tree0735f5382a05a8f60d06aefd48d324fafabeb9dd
parent192ea5bb77a7ca0b28c41f21ae6dc779dedca9da (diff)
downloadffmpeg-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.c45
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);