summaryrefslogtreecommitdiff
path: root/libavformat/aacdec.c
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 /libavformat/aacdec.c
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.
Diffstat (limited to 'libavformat/aacdec.c')
-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);