summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavformat/aacdec.c2
-rw-r--r--libavformat/aiffdec.c2
-rw-r--r--libavformat/asf.c2
-rw-r--r--libavformat/dsfdec.c2
-rw-r--r--libavformat/id3v2.c95
-rw-r--r--libavformat/id3v2.h4
-rw-r--r--libavformat/iff.c1
-rw-r--r--libavformat/omadec.c2
-rw-r--r--libavformat/wavdec.c2
-rw-r--r--tests/ref/fate/cover-art-aiff-id3v2-remux44
-rw-r--r--tests/ref/fate/cover-art-mp3-id3v2-remux16
-rw-r--r--tests/ref/fate/id3v2-priv2
-rw-r--r--tests/ref/fate/id3v2-priv-remux2
13 files changed, 82 insertions, 94 deletions
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index a0aa112a8a..ea3203df36 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -136,7 +136,7 @@ static int handle_id3(AVFormatContext *s, AVPacket *pkt)
{
AVDictionary *metadata = NULL;
AVIOContext ioctx;
- ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+ ID3v2ExtraMeta *id3v2_extra_meta;
int ret;
ret = av_append_packet(s->pb, pkt, ff_id3v2_tag_len(pkt->data) - pkt->size);
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index dcaf1560b6..1b693b71a3 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -212,7 +212,7 @@ static int aiff_read_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
AVStream * st;
AIFFInputContext *aiff = s->priv_data;
- ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+ ID3v2ExtraMeta *id3v2_extra_meta;
/* check FORM header */
filesize = get_tag(pb, &tag);
diff --git a/libavformat/asf.c b/libavformat/asf.c
index cef0f9f646..1ac8b5f078 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -255,7 +255,7 @@ fail:
static int get_id3_tag(AVFormatContext *s, int len)
{
- ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+ ID3v2ExtraMeta *id3v2_extra_meta;
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len);
if (id3v2_extra_meta) {
diff --git a/libavformat/dsfdec.c b/libavformat/dsfdec.c
index 1df163e114..2fca25ef32 100644
--- a/libavformat/dsfdec.c
+++ b/libavformat/dsfdec.c
@@ -50,7 +50,7 @@ static const uint64_t dsf_channel_layout[] = {
static void read_id3(AVFormatContext *s, uint64_t id3pos)
{
- ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+ ID3v2ExtraMeta *id3v2_extra_meta;
if (avio_seek(s->pb, id3pos, SEEK_SET) < 0)
return;
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 863709abbf..e0fef08789 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -443,12 +443,24 @@ static void read_comment(AVFormatContext *s, AVIOContext *pb, int taglen,
av_dict_set(metadata, key, (const char *) dst, dict_flags);
}
+typedef struct ExtraMetaList {
+ ID3v2ExtraMeta *head, *tail;
+} ExtraMetaList;
+
+static void list_append(ID3v2ExtraMeta *new_elem, ExtraMetaList *list)
+{
+ if (list->tail)
+ list->tail->next = new_elem;
+ else
+ list->head = new_elem;
+ list->tail = new_elem;
+}
+
/**
* Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
*/
static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
- const char *tag, ID3v2ExtraMeta **extra_meta,
- int isv34)
+ const char *tag, ExtraMetaList *extra_meta, int isv34)
{
ID3v2ExtraMetaGEOB *geob_data = NULL;
ID3v2ExtraMeta *new_extra = NULL;
@@ -505,8 +517,7 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
/* add data to the list */
new_extra->tag = "GEOB";
- new_extra->next = *extra_meta;
- *extra_meta = new_extra;
+ list_append(new_extra, extra_meta);
return;
@@ -580,8 +591,7 @@ static void rstrip_spaces(char *buf)
}
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
- const char *tag, ID3v2ExtraMeta **extra_meta,
- int isv34)
+ const char *tag, ExtraMetaList *extra_meta, int isv34)
{
int enc, pic_type;
char mimetype[64] = {0};
@@ -654,12 +664,11 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
memset(apic->buf->data + taglen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
new_extra->tag = "APIC";
- new_extra->next = *extra_meta;
- *extra_meta = new_extra;
// The description must be unique, and some ID3v2 tag writers add spaces
// to write several APIC entries with the same description.
rstrip_spaces(apic->description);
+ list_append(new_extra, extra_meta);
return;
@@ -677,7 +686,8 @@ static void free_chapter(void *obj)
av_dict_free(&chap->meta);
}
-static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ID3v2ExtraMeta **extra_meta, int isv34)
+static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len,
+ const char *ttag, ExtraMetaList *extra_meta, int isv34)
{
int taglen;
char tag[5];
@@ -721,8 +731,7 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const cha
ff_metadata_conv(&chap->meta, NULL, ff_id3v2_4_metadata_conv);
new_extra->tag = "CHAP";
- new_extra->next = *extra_meta;
- *extra_meta = new_extra;
+ list_append(new_extra, extra_meta);
return;
@@ -739,7 +748,7 @@ static void free_priv(void *obj)
}
static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
- const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
+ const char *tag, ExtraMetaList *extra_meta, int isv34)
{
ID3v2ExtraMeta *meta;
ID3v2ExtraMetaPRIV *priv;
@@ -763,8 +772,7 @@ static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
goto fail;
meta->tag = "PRIV";
- meta->next = *extra_meta;
- *extra_meta = meta;
+ list_append(meta, extra_meta);
return;
@@ -777,7 +785,7 @@ typedef struct ID3v2EMFunc {
const char *tag3;
const char *tag4;
void (*read)(AVFormatContext *s, AVIOContext *pb, int taglen,
- const char *tag, ID3v2ExtraMeta **extra_meta,
+ const char *tag, ExtraMetaList *extra_meta,
int isv34);
void (*free)(void *obj);
} ID3v2EMFunc;
@@ -811,7 +819,7 @@ static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
AVFormatContext *s, int len, uint8_t version,
- uint8_t flags, ID3v2ExtraMeta **extra_meta)
+ uint8_t flags, ExtraMetaList *extra_meta)
{
int isv34, unsync;
unsigned tlen;
@@ -1063,13 +1071,17 @@ error:
static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
AVFormatContext *s, const char *magic,
- ID3v2ExtraMeta **extra_meta, int64_t max_search_size)
+ ID3v2ExtraMeta **extra_metap, int64_t max_search_size)
{
int len, ret;
uint8_t buf[ID3v2_HEADER_SIZE];
+ ExtraMetaList extra_meta = { NULL };
int found_header;
int64_t start, off;
+ if (extra_metap)
+ *extra_metap = NULL;
+
if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
return;
@@ -1096,7 +1108,8 @@ static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
((buf[7] & 0x7f) << 14) |
((buf[8] & 0x7f) << 7) |
(buf[9] & 0x7f);
- id3v2_parse(pb, metadata, s, len, buf[3], buf[5], extra_meta);
+ id3v2_parse(pb, metadata, s, len, buf[3], buf[5],
+ extra_metap ? &extra_meta : NULL);
} else {
avio_seek(pb, off, SEEK_SET);
}
@@ -1105,6 +1118,8 @@ static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
ff_metadata_conv(metadata, NULL, id3v2_2_metadata_conv);
ff_metadata_conv(metadata, NULL, ff_id3v2_4_metadata_conv);
merge_date(metadata);
+ if (extra_metap)
+ *extra_metap = extra_meta.head;
}
void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata,
@@ -1166,55 +1181,29 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
return 0;
}
-int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
+int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta *cur)
{
- int ret = 0;
- ID3v2ExtraMeta *cur;
AVRational time_base = {1, 1000};
- ID3v2ExtraMetaCHAP **chapters = NULL;
- int num_chapters = 0;
- int i;
+ int ret;
- // since extra_meta is a linked list where elements are prepended,
- // we need to reverse the order of chapters
- for (cur = extra_meta; cur; cur = cur->next) {
+ for (unsigned i = 0; cur; cur = cur->next) {
ID3v2ExtraMetaCHAP *chap;
+ AVChapter *chapter;
if (strcmp(cur->tag, "CHAP"))
continue;
- chap = &cur->data.chap;
-
- if ((ret = av_dynarray_add_nofree(&chapters, &num_chapters, chap)) < 0)
- goto end;
- }
-
- for (i = 0; i < (num_chapters / 2); i++) {
- ID3v2ExtraMetaCHAP *right;
- int right_index;
-
- right_index = (num_chapters - 1) - i;
- right = chapters[right_index];
- chapters[right_index] = chapters[i];
- chapters[i] = right;
- }
-
- for (i = 0; i < num_chapters; i++) {
- ID3v2ExtraMetaCHAP *chap;
- AVChapter *chapter;
-
- chap = chapters[i];
- chapter = avpriv_new_chapter(s, i, time_base, chap->start, chap->end, chap->element_id);
+ chap = &cur->data.chap;
+ chapter = avpriv_new_chapter(s, i++, time_base, chap->start,
+ chap->end, chap->element_id);
if (!chapter)
continue;
if ((ret = av_dict_copy(&chapter->metadata, chap->meta, 0)) < 0)
- goto end;
+ return ret;
}
-end:
- av_freep(&chapters);
- return ret;
+ return 0;
}
int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta *extra_meta)
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index a41fb271a4..9afa5a2ddc 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -111,7 +111,7 @@ int ff_id3v2_tag_len(const uint8_t *buf);
* Read an ID3v2 tag into specified dictionary and retrieve supported extra metadata.
*
* @param metadata Parsed metadata is stored here
- * @param extra_meta If not NULL, extra metadata is parsed into a list of
+ * @param[out] extra_meta If not NULL, extra metadata is parsed into a list of
* ID3v2ExtraMeta structs and *extra_meta points to the head of the list
*/
void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char *magic, ID3v2ExtraMeta **extra_meta);
@@ -121,7 +121,7 @@ void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char *ma
*
* Data is read from and stored to AVFormatContext.
*
- * @param extra_meta If not NULL, extra metadata is parsed into a list of
+ * @param[out] extra_meta If not NULL, extra metadata is parsed into a list of
* ID3v2ExtraMeta structs and *extra_meta points to the head of the list
* @param[opt] max_search_search restrict ID3 magic number search (bytes from start)
*/
diff --git a/libavformat/iff.c b/libavformat/iff.c
index b07b6c8b18..27b5581cc3 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -315,7 +315,6 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof)
break;
case MKTAG('I','D','3',' '):
- id3v2_extra_meta = NULL;
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size);
if (id3v2_extra_meta) {
if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0 ||
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index d31b475fd2..74b32db96d 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -413,7 +413,7 @@ static int oma_read_header(AVFormatContext *s)
uint8_t buf[EA3_HEADER_SIZE];
uint8_t *edata;
AVStream *st;
- ID3v2ExtraMeta *extra_meta = NULL;
+ ID3v2ExtraMeta *extra_meta;
OMAContext *oc = s->priv_data;
ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0);
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 8214ab8498..aca9a8382b 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -549,7 +549,7 @@ static int wav_read_header(AVFormatContext *s)
break;
case MKTAG('I', 'D', '3', ' '):
case MKTAG('i', 'd', '3', ' '): {
- ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+ ID3v2ExtraMeta *id3v2_extra_meta;
ff_id3v2_read_dict(pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
if (id3v2_extra_meta) {
ff_id3v2_parse_apic(s, id3v2_extra_meta);
diff --git a/tests/ref/fate/cover-art-aiff-id3v2-remux b/tests/ref/fate/cover-art-aiff-id3v2-remux
index 207721fc71..c294c5013e 100644
--- a/tests/ref/fate/cover-art-aiff-id3v2-remux
+++ b/tests/ref/fate/cover-art-aiff-id3v2-remux
@@ -8,29 +8,29 @@ d4a9481090a8bab1a3f072a8108a1d6a *tests/data/fate/cover-art-aiff-id3v2-remux.aif
#channel_layout_name 0: stereo
#tb 1: 1/90000
#media_type 1: video
-#codec_id 1: bmp
+#codec_id 1: mjpeg
#dimensions 1: 350x350
-#sar 1: 0/1
+#sar 1: 1/1
#tb 2: 1/90000
#media_type 2: video
-#codec_id 2: png
+#codec_id 2: mjpeg
#dimensions 2: 350x350
#sar 2: 1/1
#tb 3: 1/90000
#media_type 3: video
-#codec_id 3: mjpeg
+#codec_id 3: png
#dimensions 3: 350x350
#sar 3: 1/1
#tb 4: 1/90000
#media_type 4: video
-#codec_id 4: mjpeg
+#codec_id 4: bmp
#dimensions 4: 350x350
-#sar 4: 1/1
+#sar 4: 0/1
0, 0, 0, 1024, 4096, 0xdac4695d
-1, 0, 0, 0, 368254, 0xfa7f4bd8
-2, 0, 0, 0, 184497, 0xc33f8d44
-3, 0, 0, 0, 19650, 0xd5662610
-4, 0, 0, 0, 19650, 0xd5662610
+1, 0, 0, 0, 19650, 0xd5662610
+2, 0, 0, 0, 19650, 0xd5662610
+3, 0, 0, 0, 184497, 0xc33f8d44
+4, 0, 0, 0, 368254, 0xfa7f4bd8
0, 1024, 1024, 1024, 4096, 0xad05c909
0, 2048, 2048, 1024, 4096, 0x97e3b8f8
0, 3072, 3072, 1024, 4096, 0xb08180fa
@@ -41,31 +41,31 @@ DISPOSITION:attached_pic=0
[/STREAM]
[STREAM]
index=1
-codec_name=bmp
+codec_name=mjpeg
DISPOSITION:attached_pic=1
-TAG:title=third
-TAG:comment=Conductor
+TAG:title=first
+TAG:comment=Other
[/STREAM]
[STREAM]
index=2
-codec_name=png
+codec_name=mjpeg
DISPOSITION:attached_pic=1
-TAG:title=second
-TAG:comment=Illustration
+TAG:title=fourth
+TAG:comment=Composer
[/STREAM]
[STREAM]
index=3
-codec_name=mjpeg
+codec_name=png
DISPOSITION:attached_pic=1
-TAG:title=fourth
-TAG:comment=Composer
+TAG:title=second
+TAG:comment=Illustration
[/STREAM]
[STREAM]
index=4
-codec_name=mjpeg
+codec_name=bmp
DISPOSITION:attached_pic=1
-TAG:title=first
-TAG:comment=Other
+TAG:title=third
+TAG:comment=Conductor
[/STREAM]
[FORMAT]
TAG:artist=Мельница
diff --git a/tests/ref/fate/cover-art-mp3-id3v2-remux b/tests/ref/fate/cover-art-mp3-id3v2-remux
index a3bc8c7891..713ca9e951 100644
--- a/tests/ref/fate/cover-art-mp3-id3v2-remux
+++ b/tests/ref/fate/cover-art-mp3-id3v2-remux
@@ -8,9 +8,9 @@ c1b55a9a92226cd72d3f53ccd830d127 *tests/data/fate/cover-art-mp3-id3v2-remux.mp3
#channel_layout_name 0: stereo
#tb 1: 1/90000
#media_type 1: video
-#codec_id 1: png
+#codec_id 1: mjpeg
#dimensions 1: 263x263
-#sar 1: 1/1
+#sar 1: 96/96
#tb 2: 1/90000
#media_type 2: video
#codec_id 2: bmp
@@ -18,13 +18,13 @@ c1b55a9a92226cd72d3f53ccd830d127 *tests/data/fate/cover-art-mp3-id3v2-remux.mp3
#sar 2: 0/1
#tb 3: 1/90000
#media_type 3: video
-#codec_id 3: mjpeg
+#codec_id 3: png
#dimensions 3: 263x263
-#sar 3: 96/96
+#sar 3: 1/1
0, -353590, -353590, 368640, 417, 0x15848290, S=1, 10, 0x034e0055
-1, 0, 0, 0, 165671, 0x7c1c8070
+1, 0, 0, 0, 15760, 0x71d5c418
2, 0, 0, 0, 208350, 0x291b44d1
-3, 0, 0, 0, 15760, 0x71d5c418
+3, 0, 0, 0, 165671, 0x7c1c8070
0, 15050, 15050, 368640, 418, 0x46f684a4
0, 383690, 383690, 368640, 418, 0x46f684a4
0, 752330, 752330, 368640, 418, 0x46f684a4
@@ -37,7 +37,7 @@ TAG:encoder=Lavf
[/STREAM]
[STREAM]
index=1
-codec_name=png
+codec_name=mjpeg
DISPOSITION:attached_pic=1
TAG:comment=Other
[/STREAM]
@@ -49,7 +49,7 @@ TAG:comment=Band/Orchestra
[/STREAM]
[STREAM]
index=3
-codec_name=mjpeg
+codec_name=png
DISPOSITION:attached_pic=1
TAG:comment=Other
[/STREAM]
diff --git a/tests/ref/fate/id3v2-priv b/tests/ref/fate/id3v2-priv
index 965c8695e8..8448495325 100644
--- a/tests/ref/fate/id3v2-priv
+++ b/tests/ref/fate/id3v2-priv
@@ -1,5 +1,5 @@
[FORMAT]
TAG:title=id3v2-test
-TAG:id3v2_priv.testowner=testdata
TAG:id3v2_priv.testowner2=\x00\x01\x02
+TAG:id3v2_priv.testowner=testdata
[/FORMAT]
diff --git a/tests/ref/fate/id3v2-priv-remux b/tests/ref/fate/id3v2-priv-remux
index 0fdd5d9d0a..6a8b58f27e 100644
--- a/tests/ref/fate/id3v2-priv-remux
+++ b/tests/ref/fate/id3v2-priv-remux
@@ -1,4 +1,4 @@
-3e99254aa892a9578ce31da17b012a44 *tests/data/fate/id3v2-priv-remux.mp3
+bb2816e3a05ce136e9ac14479c1ebe24 *tests/data/fate/id3v2-priv-remux.mp3
8542 tests/data/fate/id3v2-priv-remux.mp3
#tb 0: 1/14112000
#media_type 0: audio