avformat/id3v2: Don't reverse the order of id3v2 APICs

When parsing ID3v2 tags, special (non-text) metadata is not applied
directly and unconditionally; instead it is stored in a linked list
in which elements are prepended. When traversing the list to add APICs
(or private tags) at the end, the order is reversed. The same also
happens for chapters and therefore the chapter parsing code already
reverses the chapters.

This commit changes this: By keeping pointers to both head and tail
of the linked list one can preserve the order of the entries and
remove the reordering code for chapters. Only the pointer to head
will be exported: No current caller uses a nonempty list, so exporting
both head and tail is unnecessary. This removes the functionality
to combine the lists of special metadata read from different ID3v2 tags,
but that doesn't make really much sense anyway (and would be trivial
to implement if desired) and allows to remove the now unnecessary
initializations performed by the callers.

The FATE-reference for the id3v2-priv test had to be updated
because the order of the tags read into the dict is reversed;
for id3v2-priv-remux only the md5 and not the ffprobe output
of the remuxed file changes because the order of the private tags
has up until now been reversed twice.

The references for the aiff/mp3 cover-art tests needed to be updated,
because the order of the attached pics is reversed upon reading.
It is still not correct, because the muxers write the pics in the order
in which they arrive at the muxer instead of the order given by
pkt->stream_index.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
pull/362/head
Andreas Rheinhardt 4 years ago
parent 9f834a1ac1
commit 8068f2fcf3
  1. 2
      libavformat/aacdec.c
  2. 2
      libavformat/aiffdec.c
  3. 2
      libavformat/asf.c
  4. 2
      libavformat/dsfdec.c
  5. 95
      libavformat/id3v2.c
  6. 4
      libavformat/id3v2.h
  7. 1
      libavformat/iff.c
  8. 2
      libavformat/omadec.c
  9. 2
      libavformat/wavdec.c
  10. 44
      tests/ref/fate/cover-art-aiff-id3v2-remux
  11. 16
      tests/ref/fate/cover-art-mp3-id3v2-remux
  12. 2
      tests/ref/fate/id3v2-priv
  13. 2
      tests/ref/fate/id3v2-priv-remux

@ -136,7 +136,7 @@ static int handle_id3(AVFormatContext *s, AVPacket *pkt)
{ {
AVDictionary *metadata = NULL; AVDictionary *metadata = NULL;
AVIOContext ioctx; AVIOContext ioctx;
ID3v2ExtraMeta *id3v2_extra_meta = NULL; ID3v2ExtraMeta *id3v2_extra_meta;
int ret; int ret;
ret = av_append_packet(s->pb, pkt, ff_id3v2_tag_len(pkt->data) - pkt->size); ret = av_append_packet(s->pb, pkt, ff_id3v2_tag_len(pkt->data) - pkt->size);

@ -212,7 +212,7 @@ static int aiff_read_header(AVFormatContext *s)
AVIOContext *pb = s->pb; AVIOContext *pb = s->pb;
AVStream * st; AVStream * st;
AIFFInputContext *aiff = s->priv_data; AIFFInputContext *aiff = s->priv_data;
ID3v2ExtraMeta *id3v2_extra_meta = NULL; ID3v2ExtraMeta *id3v2_extra_meta;
/* check FORM header */ /* check FORM header */
filesize = get_tag(pb, &tag); filesize = get_tag(pb, &tag);

@ -255,7 +255,7 @@ fail:
static int get_id3_tag(AVFormatContext *s, int len) 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); ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len);
if (id3v2_extra_meta) { if (id3v2_extra_meta) {

@ -50,7 +50,7 @@ static const uint64_t dsf_channel_layout[] = {
static void read_id3(AVFormatContext *s, uint64_t id3pos) 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) if (avio_seek(s->pb, id3pos, SEEK_SET) < 0)
return; return;

@ -443,12 +443,24 @@ static void read_comment(AVFormatContext *s, AVIOContext *pb, int taglen,
av_dict_set(metadata, key, (const char *) dst, dict_flags); 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. * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
*/ */
static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
const char *tag, ID3v2ExtraMeta **extra_meta, const char *tag, ExtraMetaList *extra_meta, int isv34)
int isv34)
{ {
ID3v2ExtraMetaGEOB *geob_data = NULL; ID3v2ExtraMetaGEOB *geob_data = NULL;
ID3v2ExtraMeta *new_extra = NULL; ID3v2ExtraMeta *new_extra = NULL;
@ -505,8 +517,7 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
/* add data to the list */ /* add data to the list */
new_extra->tag = "GEOB"; new_extra->tag = "GEOB";
new_extra->next = *extra_meta; list_append(new_extra, extra_meta);
*extra_meta = new_extra;
return; return;
@ -580,8 +591,7 @@ static void rstrip_spaces(char *buf)
} }
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
const char *tag, ID3v2ExtraMeta **extra_meta, const char *tag, ExtraMetaList *extra_meta, int isv34)
int isv34)
{ {
int enc, pic_type; int enc, pic_type;
char mimetype[64] = {0}; 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); memset(apic->buf->data + taglen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
new_extra->tag = "APIC"; 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 // The description must be unique, and some ID3v2 tag writers add spaces
// to write several APIC entries with the same description. // to write several APIC entries with the same description.
rstrip_spaces(apic->description); rstrip_spaces(apic->description);
list_append(new_extra, extra_meta);
return; return;
@ -677,7 +686,8 @@ static void free_chapter(void *obj)
av_dict_free(&chap->meta); 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; int taglen;
char tag[5]; 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); ff_metadata_conv(&chap->meta, NULL, ff_id3v2_4_metadata_conv);
new_extra->tag = "CHAP"; new_extra->tag = "CHAP";
new_extra->next = *extra_meta; list_append(new_extra, extra_meta);
*extra_meta = new_extra;
return; return;
@ -739,7 +748,7 @@ static void free_priv(void *obj)
} }
static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen, 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; ID3v2ExtraMeta *meta;
ID3v2ExtraMetaPRIV *priv; ID3v2ExtraMetaPRIV *priv;
@ -763,8 +772,7 @@ static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
goto fail; goto fail;
meta->tag = "PRIV"; meta->tag = "PRIV";
meta->next = *extra_meta; list_append(meta, extra_meta);
*extra_meta = meta;
return; return;
@ -777,7 +785,7 @@ typedef struct ID3v2EMFunc {
const char *tag3; const char *tag3;
const char *tag4; const char *tag4;
void (*read)(AVFormatContext *s, AVIOContext *pb, int taglen, void (*read)(AVFormatContext *s, AVIOContext *pb, int taglen,
const char *tag, ID3v2ExtraMeta **extra_meta, const char *tag, ExtraMetaList *extra_meta,
int isv34); int isv34);
void (*free)(void *obj); void (*free)(void *obj);
} ID3v2EMFunc; } 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, static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
AVFormatContext *s, int len, uint8_t version, AVFormatContext *s, int len, uint8_t version,
uint8_t flags, ID3v2ExtraMeta **extra_meta) uint8_t flags, ExtraMetaList *extra_meta)
{ {
int isv34, unsync; int isv34, unsync;
unsigned tlen; unsigned tlen;
@ -1063,13 +1071,17 @@ error:
static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata, static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
AVFormatContext *s, const char *magic, AVFormatContext *s, const char *magic,
ID3v2ExtraMeta **extra_meta, int64_t max_search_size) ID3v2ExtraMeta **extra_metap, int64_t max_search_size)
{ {
int len, ret; int len, ret;
uint8_t buf[ID3v2_HEADER_SIZE]; uint8_t buf[ID3v2_HEADER_SIZE];
ExtraMetaList extra_meta = { NULL };
int found_header; int found_header;
int64_t start, off; int64_t start, off;
if (extra_metap)
*extra_metap = NULL;
if (max_search_size && max_search_size < ID3v2_HEADER_SIZE) if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
return; return;
@ -1096,7 +1108,8 @@ static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
((buf[7] & 0x7f) << 14) | ((buf[7] & 0x7f) << 14) |
((buf[8] & 0x7f) << 7) | ((buf[8] & 0x7f) << 7) |
(buf[9] & 0x7f); (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 { } else {
avio_seek(pb, off, SEEK_SET); 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, id3v2_2_metadata_conv);
ff_metadata_conv(metadata, NULL, ff_id3v2_4_metadata_conv); ff_metadata_conv(metadata, NULL, ff_id3v2_4_metadata_conv);
merge_date(metadata); merge_date(metadata);
if (extra_metap)
*extra_metap = extra_meta.head;
} }
void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, 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; 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}; AVRational time_base = {1, 1000};
ID3v2ExtraMetaCHAP **chapters = NULL; int ret;
int num_chapters = 0;
int i;
// since extra_meta is a linked list where elements are prepended, for (unsigned i = 0; cur; cur = cur->next) {
// we need to reverse the order of chapters
for (cur = extra_meta; cur; cur = cur->next) {
ID3v2ExtraMetaCHAP *chap; ID3v2ExtraMetaCHAP *chap;
AVChapter *chapter;
if (strcmp(cur->tag, "CHAP")) if (strcmp(cur->tag, "CHAP"))
continue; 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]; chap = &cur->data.chap;
chapters[i] = right; chapter = avpriv_new_chapter(s, i++, time_base, chap->start,
} chap->end, chap->element_id);
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);
if (!chapter) if (!chapter)
continue; continue;
if ((ret = av_dict_copy(&chapter->metadata, chap->meta, 0)) < 0) if ((ret = av_dict_copy(&chapter->metadata, chap->meta, 0)) < 0)
goto end; return ret;
} }
end: return 0;
av_freep(&chapters);
return ret;
} }
int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta *extra_meta) int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta *extra_meta)

@ -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. * Read an ID3v2 tag into specified dictionary and retrieve supported extra metadata.
* *
* @param metadata Parsed metadata is stored here * @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 * 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); 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. * 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 * 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) * @param[opt] max_search_search restrict ID3 magic number search (bytes from start)
*/ */

@ -315,7 +315,6 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof)
break; break;
case MKTAG('I','D','3',' '): case MKTAG('I','D','3',' '):
id3v2_extra_meta = NULL;
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size);
if (id3v2_extra_meta) { if (id3v2_extra_meta) {
if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0 || if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0 ||

@ -413,7 +413,7 @@ static int oma_read_header(AVFormatContext *s)
uint8_t buf[EA3_HEADER_SIZE]; uint8_t buf[EA3_HEADER_SIZE];
uint8_t *edata; uint8_t *edata;
AVStream *st; AVStream *st;
ID3v2ExtraMeta *extra_meta = NULL; ID3v2ExtraMeta *extra_meta;
OMAContext *oc = s->priv_data; OMAContext *oc = s->priv_data;
ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0); ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0);

@ -549,7 +549,7 @@ static int wav_read_header(AVFormatContext *s)
break; break;
case MKTAG('I', 'D', '3', ' '): case MKTAG('I', 'D', '3', ' '):
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); ff_id3v2_read_dict(pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
if (id3v2_extra_meta) { if (id3v2_extra_meta) {
ff_id3v2_parse_apic(s, id3v2_extra_meta); ff_id3v2_parse_apic(s, id3v2_extra_meta);

@ -8,29 +8,29 @@ d4a9481090a8bab1a3f072a8108a1d6a *tests/data/fate/cover-art-aiff-id3v2-remux.aif
#channel_layout_name 0: stereo #channel_layout_name 0: stereo
#tb 1: 1/90000 #tb 1: 1/90000
#media_type 1: video #media_type 1: video
#codec_id 1: bmp #codec_id 1: mjpeg
#dimensions 1: 350x350 #dimensions 1: 350x350
#sar 1: 0/1 #sar 1: 1/1
#tb 2: 1/90000 #tb 2: 1/90000
#media_type 2: video #media_type 2: video
#codec_id 2: png #codec_id 2: mjpeg
#dimensions 2: 350x350 #dimensions 2: 350x350
#sar 2: 1/1 #sar 2: 1/1
#tb 3: 1/90000 #tb 3: 1/90000
#media_type 3: video #media_type 3: video
#codec_id 3: mjpeg #codec_id 3: png
#dimensions 3: 350x350 #dimensions 3: 350x350
#sar 3: 1/1 #sar 3: 1/1
#tb 4: 1/90000 #tb 4: 1/90000
#media_type 4: video #media_type 4: video
#codec_id 4: mjpeg #codec_id 4: bmp
#dimensions 4: 350x350 #dimensions 4: 350x350
#sar 4: 1/1 #sar 4: 0/1
0, 0, 0, 1024, 4096, 0xdac4695d 0, 0, 0, 1024, 4096, 0xdac4695d
1, 0, 0, 0, 368254, 0xfa7f4bd8 1, 0, 0, 0, 19650, 0xd5662610
2, 0, 0, 0, 184497, 0xc33f8d44 2, 0, 0, 0, 19650, 0xd5662610
3, 0, 0, 0, 19650, 0xd5662610 3, 0, 0, 0, 184497, 0xc33f8d44
4, 0, 0, 0, 19650, 0xd5662610 4, 0, 0, 0, 368254, 0xfa7f4bd8
0, 1024, 1024, 1024, 4096, 0xad05c909 0, 1024, 1024, 1024, 4096, 0xad05c909
0, 2048, 2048, 1024, 4096, 0x97e3b8f8 0, 2048, 2048, 1024, 4096, 0x97e3b8f8
0, 3072, 3072, 1024, 4096, 0xb08180fa 0, 3072, 3072, 1024, 4096, 0xb08180fa
@ -41,31 +41,31 @@ DISPOSITION:attached_pic=0
[/STREAM] [/STREAM]
[STREAM] [STREAM]
index=1 index=1
codec_name=bmp codec_name=mjpeg
DISPOSITION:attached_pic=1 DISPOSITION:attached_pic=1
TAG:title=third TAG:title=first
TAG:comment=Conductor TAG:comment=Other
[/STREAM] [/STREAM]
[STREAM] [STREAM]
index=2 index=2
codec_name=png codec_name=mjpeg
DISPOSITION:attached_pic=1 DISPOSITION:attached_pic=1
TAG:title=second TAG:title=fourth
TAG:comment=Illustration TAG:comment=Composer
[/STREAM] [/STREAM]
[STREAM] [STREAM]
index=3 index=3
codec_name=mjpeg codec_name=png
DISPOSITION:attached_pic=1 DISPOSITION:attached_pic=1
TAG:title=fourth TAG:title=second
TAG:comment=Composer TAG:comment=Illustration
[/STREAM] [/STREAM]
[STREAM] [STREAM]
index=4 index=4
codec_name=mjpeg codec_name=bmp
DISPOSITION:attached_pic=1 DISPOSITION:attached_pic=1
TAG:title=first TAG:title=third
TAG:comment=Other TAG:comment=Conductor
[/STREAM] [/STREAM]
[FORMAT] [FORMAT]
TAG:artist=Мельница TAG:artist=Мельница

@ -8,9 +8,9 @@ c1b55a9a92226cd72d3f53ccd830d127 *tests/data/fate/cover-art-mp3-id3v2-remux.mp3
#channel_layout_name 0: stereo #channel_layout_name 0: stereo
#tb 1: 1/90000 #tb 1: 1/90000
#media_type 1: video #media_type 1: video
#codec_id 1: png #codec_id 1: mjpeg
#dimensions 1: 263x263 #dimensions 1: 263x263
#sar 1: 1/1 #sar 1: 96/96
#tb 2: 1/90000 #tb 2: 1/90000
#media_type 2: video #media_type 2: video
#codec_id 2: bmp #codec_id 2: bmp
@ -18,13 +18,13 @@ c1b55a9a92226cd72d3f53ccd830d127 *tests/data/fate/cover-art-mp3-id3v2-remux.mp3
#sar 2: 0/1 #sar 2: 0/1
#tb 3: 1/90000 #tb 3: 1/90000
#media_type 3: video #media_type 3: video
#codec_id 3: mjpeg #codec_id 3: png
#dimensions 3: 263x263 #dimensions 3: 263x263
#sar 3: 96/96 #sar 3: 1/1
0, -353590, -353590, 368640, 417, 0x15848290, S=1, 10, 0x034e0055 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 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, 15050, 15050, 368640, 418, 0x46f684a4
0, 383690, 383690, 368640, 418, 0x46f684a4 0, 383690, 383690, 368640, 418, 0x46f684a4
0, 752330, 752330, 368640, 418, 0x46f684a4 0, 752330, 752330, 368640, 418, 0x46f684a4
@ -37,7 +37,7 @@ TAG:encoder=Lavf
[/STREAM] [/STREAM]
[STREAM] [STREAM]
index=1 index=1
codec_name=png codec_name=mjpeg
DISPOSITION:attached_pic=1 DISPOSITION:attached_pic=1
TAG:comment=Other TAG:comment=Other
[/STREAM] [/STREAM]
@ -49,7 +49,7 @@ TAG:comment=Band/Orchestra
[/STREAM] [/STREAM]
[STREAM] [STREAM]
index=3 index=3
codec_name=mjpeg codec_name=png
DISPOSITION:attached_pic=1 DISPOSITION:attached_pic=1
TAG:comment=Other TAG:comment=Other
[/STREAM] [/STREAM]

@ -1,5 +1,5 @@
[FORMAT] [FORMAT]
TAG:title=id3v2-test TAG:title=id3v2-test
TAG:id3v2_priv.testowner=testdata
TAG:id3v2_priv.testowner2=\x00\x01\x02 TAG:id3v2_priv.testowner2=\x00\x01\x02
TAG:id3v2_priv.testowner=testdata
[/FORMAT] [/FORMAT]

@ -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 8542 tests/data/fate/id3v2-priv-remux.mp3
#tb 0: 1/14112000 #tb 0: 1/14112000
#media_type 0: audio #media_type 0: audio

Loading…
Cancel
Save