Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
0671adbb
Commit
0671adbb
authored
May 01, 2013
by
Luca Barbato
Committed by
Diego Biurrun
May 02, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
id3v2: K&R formatting cosmetics
Signed-off-by:
Diego Biurrun
<
diego@biurrun.de
>
parent
a650c906
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
147 additions
and
126 deletions
+147
-126
id3v2.c
libavformat/id3v2.c
+147
-126
No files found.
libavformat/id3v2.c
View file @
0671adbb
...
...
@@ -19,72 +19,71 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "id3v2.h"
#include "id3v1.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/intreadwrite.h"
#include "avio_internal.h"
#include "internal.h"
#include "id3v1.h"
#include "id3v2.h"
const
AVMetadataConv
ff_id3v2_34_metadata_conv
[]
=
{
{
"TALB"
,
"album"
},
{
"TCOM"
,
"composer"
},
{
"TCON"
,
"genre"
},
{
"TCOP"
,
"copyright"
},
{
"TENC"
,
"encoded_by"
},
{
"TIT2"
,
"title"
},
{
"TLAN"
,
"language"
},
{
"TPE1"
,
"artist"
},
{
"TPE2"
,
"album_artist"
},
{
"TPE3"
,
"performer"
},
{
"TPOS"
,
"disc"
},
{
"TPUB"
,
"publisher"
},
{
"TRCK"
,
"track"
},
{
"TSSE"
,
"encoder"
},
{
"TALB"
,
"album"
},
{
"TCOM"
,
"composer"
},
{
"TCON"
,
"genre"
},
{
"TCOP"
,
"copyright"
},
{
"TENC"
,
"encoded_by"
},
{
"TIT2"
,
"title"
},
{
"TLAN"
,
"language"
},
{
"TPE1"
,
"artist"
},
{
"TPE2"
,
"album_artist"
},
{
"TPE3"
,
"performer"
},
{
"TPOS"
,
"disc"
},
{
"TPUB"
,
"publisher"
},
{
"TRCK"
,
"track"
},
{
"TSSE"
,
"encoder"
},
{
0
}
};
const
AVMetadataConv
ff_id3v2_4_metadata_conv
[]
=
{
{
"TDRL"
,
"date"
},
{
"TDRC"
,
"date"
},
{
"TDEN"
,
"creation_time"
},
{
"TSOA"
,
"album-sort"
},
{
"TSOP"
,
"artist-sort"
},
{
"TSOT"
,
"title-sort"
},
{
"TDRL"
,
"date"
},
{
"TDRC"
,
"date"
},
{
"TDEN"
,
"creation_time"
},
{
"TSOA"
,
"album-sort"
},
{
"TSOP"
,
"artist-sort"
},
{
"TSOT"
,
"title-sort"
},
{
0
}
};
static
const
AVMetadataConv
id3v2_2_metadata_conv
[]
=
{
{
"TAL"
,
"album"
},
{
"TCO"
,
"genre"
},
{
"TT2"
,
"title"
},
{
"TEN"
,
"encoded_by"
},
{
"TP1"
,
"artist"
},
{
"TP2"
,
"album_artist"
},
{
"TP3"
,
"performer"
},
{
"TRK"
,
"track"
},
{
"TAL"
,
"album"
},
{
"TCO"
,
"genre"
},
{
"TT2"
,
"title"
},
{
"TEN"
,
"encoded_by"
},
{
"TP1"
,
"artist"
},
{
"TP2"
,
"album_artist"
},
{
"TP3"
,
"performer"
},
{
"TRK"
,
"track"
},
{
0
}
};
const
char
ff_id3v2_tags
[][
4
]
=
{
"TALB"
,
"TBPM"
,
"TCOM"
,
"TCON"
,
"TCOP"
,
"TDLY"
,
"TENC"
,
"TEXT"
,
"TFLT"
,
"TIT1"
,
"TIT2"
,
"TIT3"
,
"TKEY"
,
"TLAN"
,
"TLEN"
,
"TMED"
,
"TOAL"
,
"TOFN"
,
"TOLY"
,
"TOPE"
,
"TOWN"
,
"TPE1"
,
"TPE2"
,
"TPE3"
,
"TPE4"
,
"TPOS"
,
"TPUB"
,
"TRCK"
,
"TRSN"
,
"TRSO"
,
"TSRC"
,
"TSSE"
,
{
0
},
"TALB"
,
"TBPM"
,
"TCOM"
,
"TCON"
,
"TCOP"
,
"TDLY"
,
"TENC"
,
"TEXT"
,
"TFLT"
,
"TIT1"
,
"TIT2"
,
"TIT3"
,
"TKEY"
,
"TLAN"
,
"TLEN"
,
"TMED"
,
"TOAL"
,
"TOFN"
,
"TOLY"
,
"TOPE"
,
"TOWN"
,
"TPE1"
,
"TPE2"
,
"TPE3"
,
"TPE4"
,
"TPOS"
,
"TPUB"
,
"TRCK"
,
"TRSN"
,
"TRSO"
,
"TSRC"
,
"TSSE"
,
{
0
},
};
const
char
ff_id3v2_4_tags
[][
4
]
=
{
"TDEN"
,
"TDOR"
,
"TDRC"
,
"TDRL"
,
"TDTG"
,
"TIPL"
,
"TMCL"
,
"TMOO"
,
"TPRO"
,
"TSOA"
,
"TSOP"
,
"TSOT"
,
"TSST"
,
{
0
},
"TDEN"
,
"TDOR"
,
"TDRC"
,
"TDRL"
,
"TDTG"
,
"TIPL"
,
"TMCL"
,
"TMOO"
,
"TPRO"
,
"TSOA"
,
"TSOP"
,
"TSOT"
,
"TSST"
,
{
0
},
};
const
char
ff_id3v2_3_tags
[][
4
]
=
{
"TDAT"
,
"TIME"
,
"TORY"
,
"TRDA"
,
"TSIZ"
,
"TYER"
,
{
0
},
"TDAT"
,
"TIME"
,
"TORY"
,
"TRDA"
,
"TSIZ"
,
"TYER"
,
{
0
},
};
const
char
*
ff_id3v2_picture_types
[
21
]
=
{
...
...
@@ -112,36 +111,36 @@ const char *ff_id3v2_picture_types[21] = {
};
const
CodecMime
ff_id3v2_mime_tags
[]
=
{
{
"image/gif"
,
AV_CODEC_ID_GIF
},
{
"image/jpeg"
,
AV_CODEC_ID_MJPEG
},
{
"image/jpg"
,
AV_CODEC_ID_MJPEG
},
{
"image/png"
,
AV_CODEC_ID_PNG
},
{
"image/tiff"
,
AV_CODEC_ID_TIFF
},
{
"image/bmp"
,
AV_CODEC_ID_BMP
},
{
"JPG"
,
AV_CODEC_ID_MJPEG
},
/* ID3v2.2 */
{
"PNG"
,
AV_CODEC_ID_PNG
},
/* ID3v2.2 */
{
""
,
AV_CODEC_ID_NONE
},
{
"image/gif"
,
AV_CODEC_ID_GIF
},
{
"image/jpeg"
,
AV_CODEC_ID_MJPEG
},
{
"image/jpg"
,
AV_CODEC_ID_MJPEG
},
{
"image/png"
,
AV_CODEC_ID_PNG
},
{
"image/tiff"
,
AV_CODEC_ID_TIFF
},
{
"image/bmp"
,
AV_CODEC_ID_BMP
},
{
"JPG"
,
AV_CODEC_ID_MJPEG
},
/* ID3v2.2 */
{
"PNG"
,
AV_CODEC_ID_PNG
},
/* ID3v2.2 */
{
""
,
AV_CODEC_ID_NONE
},
};
int
ff_id3v2_match
(
const
uint8_t
*
buf
,
const
char
*
magic
)
int
ff_id3v2_match
(
const
uint8_t
*
buf
,
const
char
*
magic
)
{
return
buf
[
0
]
==
magic
[
0
]
&&
buf
[
1
]
==
magic
[
1
]
&&
buf
[
2
]
==
magic
[
2
]
&&
buf
[
3
]
!=
0xff
&&
buf
[
4
]
!=
0xff
&&
(
buf
[
6
]
&
0x80
)
==
0
&&
(
buf
[
7
]
&
0x80
)
==
0
&&
(
buf
[
8
]
&
0x80
)
==
0
&&
(
buf
[
9
]
&
0x80
)
==
0
;
buf
[
3
]
!=
0xff
&&
buf
[
4
]
!=
0xff
&&
(
buf
[
6
]
&
0x80
)
==
0
&&
(
buf
[
7
]
&
0x80
)
==
0
&&
(
buf
[
8
]
&
0x80
)
==
0
&&
(
buf
[
9
]
&
0x80
)
==
0
;
}
int
ff_id3v2_tag_len
(
const
uint8_t
*
buf
)
int
ff_id3v2_tag_len
(
const
uint8_t
*
buf
)
{
int
len
=
((
buf
[
6
]
&
0x7f
)
<<
21
)
+
((
buf
[
7
]
&
0x7f
)
<<
14
)
+
((
buf
[
8
]
&
0x7f
)
<<
7
)
+
(
buf
[
9
]
&
0x7f
)
+
(
buf
[
9
]
&
0x7f
)
+
ID3v2_HEADER_SIZE
;
if
(
buf
[
5
]
&
0x10
)
len
+=
ID3v2_HEADER_SIZE
;
...
...
@@ -197,7 +196,6 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
}
switch
(
encoding
)
{
case
ID3v2_ENCODING_ISO8859
:
while
(
left
&&
ch
)
{
ch
=
avio_r8
(
pb
);
...
...
@@ -233,7 +231,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
PUT_UTF8
(
ch
,
tmp
,
avio_w8
(
dynbuf
,
tmp
);)
}
if
(
left
<
0
)
left
+=
2
;
/* did not read last char from pb */
left
+=
2
;
/* did not read last char from pb */
break
;
case
ID3v2_ENCODING_UTF8
:
...
...
@@ -259,7 +257,8 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
/**
* Parse a text tag.
*/
static
void
read_ttag
(
AVFormatContext
*
s
,
AVIOContext
*
pb
,
int
taglen
,
const
char
*
key
)
static
void
read_ttag
(
AVFormatContext
*
s
,
AVIOContext
*
pb
,
int
taglen
,
const
char
*
key
)
{
uint8_t
*
dst
;
int
encoding
,
dict_flags
=
AV_DICT_DONT_OVERWRITE
|
AV_DICT_DONT_STRDUP_VAL
;
...
...
@@ -276,9 +275,9 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
return
;
}
if
(
!
(
strcmp
(
key
,
"TCON"
)
&&
strcmp
(
key
,
"TCO"
))
&&
(
sscanf
(
dst
,
"(%d)"
,
&
genre
)
==
1
||
sscanf
(
dst
,
"%d"
,
&
genre
)
==
1
)
&&
genre
<=
ID3v1_GENRE_MAX
)
{
if
(
!
(
strcmp
(
key
,
"TCON"
)
&&
strcmp
(
key
,
"TCO"
))
&&
(
sscanf
(
dst
,
"(%d)"
,
&
genre
)
==
1
||
sscanf
(
dst
,
"%d"
,
&
genre
)
==
1
)
&&
genre
<=
ID3v1_GENRE_MAX
)
{
av_freep
(
&
dst
);
dst
=
av_strdup
(
ff_id3v1_genre_str
[
genre
]);
}
else
if
(
!
(
strcmp
(
key
,
"TXXX"
)
&&
strcmp
(
key
,
"TXX"
)))
{
...
...
@@ -300,10 +299,11 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
/**
* Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
*/
static
void
read_geobtag
(
AVFormatContext
*
s
,
AVIOContext
*
pb
,
int
taglen
,
char
*
tag
,
ID3v2ExtraMeta
**
extra_meta
)
static
void
read_geobtag
(
AVFormatContext
*
s
,
AVIOContext
*
pb
,
int
taglen
,
char
*
tag
,
ID3v2ExtraMeta
**
extra_meta
)
{
ID3v2ExtraMetaGEOB
*
geob_data
=
NULL
;
ID3v2ExtraMeta
*
new_extra
=
NULL
;
ID3v2ExtraMeta
*
new_extra
=
NULL
;
char
encoding
;
unsigned
int
len
;
...
...
@@ -312,13 +312,15 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
geob_data
=
av_mallocz
(
sizeof
(
ID3v2ExtraMetaGEOB
));
if
(
!
geob_data
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Failed to alloc %zu bytes
\n
"
,
sizeof
(
ID3v2ExtraMetaGEOB
));
av_log
(
s
,
AV_LOG_ERROR
,
"Failed to alloc %zu bytes
\n
"
,
sizeof
(
ID3v2ExtraMetaGEOB
));
return
;
}
new_extra
=
av_mallocz
(
sizeof
(
ID3v2ExtraMeta
));
if
(
!
new_extra
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Failed to alloc %zu bytes
\n
"
,
sizeof
(
ID3v2ExtraMeta
));
av_log
(
s
,
AV_LOG_ERROR
,
"Failed to alloc %zu bytes
\n
"
,
sizeof
(
ID3v2ExtraMeta
));
goto
fail
;
}
...
...
@@ -327,18 +329,19 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
taglen
--
;
/* read MIME type (always ISO-8859) */
if
(
decode_str
(
s
,
pb
,
ID3v2_ENCODING_ISO8859
,
&
geob_data
->
mime_type
,
&
taglen
)
<
0
||
taglen
<=
0
)
if
(
decode_str
(
s
,
pb
,
ID3v2_ENCODING_ISO8859
,
&
geob_data
->
mime_type
,
&
taglen
)
<
0
||
taglen
<=
0
)
goto
fail
;
/* read file name */
if
(
decode_str
(
s
,
pb
,
encoding
,
&
geob_data
->
file_name
,
&
taglen
)
<
0
||
taglen
<=
0
)
if
(
decode_str
(
s
,
pb
,
encoding
,
&
geob_data
->
file_name
,
&
taglen
)
<
0
||
taglen
<=
0
)
goto
fail
;
/* read content description */
if
(
decode_str
(
s
,
pb
,
encoding
,
&
geob_data
->
description
,
&
taglen
)
<
0
||
taglen
<
0
)
if
(
decode_str
(
s
,
pb
,
encoding
,
&
geob_data
->
description
,
&
taglen
)
<
0
||
taglen
<
0
)
goto
fail
;
if
(
taglen
)
{
...
...
@@ -349,18 +352,19 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
goto
fail
;
}
if
((
len
=
avio_read
(
pb
,
geob_data
->
data
,
taglen
))
<
taglen
)
av_log
(
s
,
AV_LOG_WARNING
,
"Error reading GEOB frame, data truncated.
\n
"
);
av_log
(
s
,
AV_LOG_WARNING
,
"Error reading GEOB frame, data truncated.
\n
"
);
geob_data
->
datasize
=
len
;
}
else
{
geob_data
->
data
=
NULL
;
geob_data
->
data
=
NULL
;
geob_data
->
datasize
=
0
;
}
/* add data to the list */
new_extra
->
tag
=
"GEOB"
;
new_extra
->
tag
=
"GEOB"
;
new_extra
->
data
=
geob_data
;
new_extra
->
next
=
*
extra_meta
;
*
extra_meta
=
new_extra
;
*
extra_meta
=
new_extra
;
return
;
...
...
@@ -373,11 +377,12 @@ fail:
static
int
is_number
(
const
char
*
str
)
{
while
(
*
str
>=
'0'
&&
*
str
<=
'9'
)
str
++
;
while
(
*
str
>=
'0'
&&
*
str
<=
'9'
)
str
++
;
return
!*
str
;
}
static
AVDictionaryEntry
*
get_date_tag
(
AVDictionary
*
m
,
const
char
*
tag
)
static
AVDictionaryEntry
*
get_date_tag
(
AVDictionary
*
m
,
const
char
*
tag
)
{
AVDictionaryEntry
*
t
;
if
((
t
=
av_dict_get
(
m
,
tag
,
NULL
,
AV_DICT_MATCH_CASE
))
&&
...
...
@@ -389,28 +394,29 @@ static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
static
void
merge_date
(
AVDictionary
**
m
)
{
AVDictionaryEntry
*
t
;
char
date
[
17
]
=
{
0
};
// YYYY-MM-DD hh:mm
char
date
[
17
]
=
{
0
};
// YYYY-MM-DD hh:mm
if
(
!
(
t
=
get_date_tag
(
*
m
,
"TYER"
))
&&
!
(
t
=
get_date_tag
(
*
m
,
"TYE"
)))
return
;
av_strlcpy
(
date
,
t
->
value
,
5
);
av_dict_set
(
m
,
"TYER"
,
NULL
,
0
);
av_dict_set
(
m
,
"TYE"
,
NULL
,
0
);
av_dict_set
(
m
,
"TYE"
,
NULL
,
0
);
if
(
!
(
t
=
get_date_tag
(
*
m
,
"TDAT"
))
&&
!
(
t
=
get_date_tag
(
*
m
,
"TDA"
)))
goto
finish
;
snprintf
(
date
+
4
,
sizeof
(
date
)
-
4
,
"-%.2s-%.2s"
,
t
->
value
+
2
,
t
->
value
);
av_dict_set
(
m
,
"TDAT"
,
NULL
,
0
);
av_dict_set
(
m
,
"TDA"
,
NULL
,
0
);
av_dict_set
(
m
,
"TDA"
,
NULL
,
0
);
if
(
!
(
t
=
get_date_tag
(
*
m
,
"TIME"
))
&&
!
(
t
=
get_date_tag
(
*
m
,
"TIM"
)))
goto
finish
;
snprintf
(
date
+
10
,
sizeof
(
date
)
-
10
,
" %.2s:%.2s"
,
t
->
value
,
t
->
value
+
2
);
snprintf
(
date
+
10
,
sizeof
(
date
)
-
10
,
" %.2s:%.2s"
,
t
->
value
,
t
->
value
+
2
);
av_dict_set
(
m
,
"TIME"
,
NULL
,
0
);
av_dict_set
(
m
,
"TIM"
,
NULL
,
0
);
av_dict_set
(
m
,
"TIM"
,
NULL
,
0
);
finish:
if
(
date
[
0
])
...
...
@@ -425,15 +431,16 @@ static void free_apic(void *obj)
av_freep
(
&
apic
);
}
static
void
read_apic
(
AVFormatContext
*
s
,
AVIOContext
*
pb
,
int
taglen
,
char
*
tag
,
ID3v2ExtraMeta
**
extra_meta
)
static
void
read_apic
(
AVFormatContext
*
s
,
AVIOContext
*
pb
,
int
taglen
,
char
*
tag
,
ID3v2ExtraMeta
**
extra_meta
)
{
int
enc
,
pic_type
;
char
mimetype
[
64
];
const
CodecMime
*
mime
=
ff_id3v2_mime_tags
;
enum
AVCodecID
id
=
AV_CODEC_ID_NONE
;
ID3v2ExtraMetaAPIC
*
apic
=
NULL
;
char
mimetype
[
64
];
const
CodecMime
*
mime
=
ff_id3v2_mime_tags
;
enum
AVCodecID
id
=
AV_CODEC_ID_NONE
;
ID3v2ExtraMetaAPIC
*
apic
=
NULL
;
ID3v2ExtraMeta
*
new_extra
=
NULL
;
int64_t
end
=
avio_tell
(
pb
)
+
taglen
;
int64_t
end
=
avio_tell
(
pb
)
+
taglen
;
if
(
taglen
<=
4
)
goto
fail
;
...
...
@@ -456,7 +463,8 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
mime
++
;
}
if
(
id
==
AV_CODEC_ID_NONE
)
{
av_log
(
s
,
AV_LOG_WARNING
,
"Unknown attached picture mimetype: %s, skipping.
\n
"
,
mimetype
);
av_log
(
s
,
AV_LOG_WARNING
,
"Unknown attached picture mimetype: %s, skipping.
\n
"
,
mimetype
);
goto
fail
;
}
apic
->
id
=
id
;
...
...
@@ -465,14 +473,16 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
pic_type
=
avio_r8
(
pb
);
taglen
--
;
if
(
pic_type
<
0
||
pic_type
>=
FF_ARRAY_ELEMS
(
ff_id3v2_picture_types
))
{
av_log
(
s
,
AV_LOG_WARNING
,
"Unknown attached picture type %d.
\n
"
,
pic_type
);
av_log
(
s
,
AV_LOG_WARNING
,
"Unknown attached picture type %d.
\n
"
,
pic_type
);
pic_type
=
0
;
}
apic
->
type
=
ff_id3v2_picture_types
[
pic_type
];
/* description and picture data */
if
(
decode_str
(
s
,
pb
,
enc
,
&
apic
->
description
,
&
taglen
)
<
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Error decoding attached picture description.
\n
"
);
av_log
(
s
,
AV_LOG_ERROR
,
"Error decoding attached picture description.
\n
"
);
goto
fail
;
}
...
...
@@ -481,10 +491,10 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
goto
fail
;
memset
(
apic
->
buf
->
data
+
taglen
,
0
,
FF_INPUT_BUFFER_PADDING_SIZE
);
new_extra
->
tag
=
"APIC"
;
new_extra
->
data
=
apic
;
new_extra
->
next
=
*
extra_meta
;
*
extra_meta
=
new_extra
;
new_extra
->
tag
=
"APIC"
;
new_extra
->
data
=
apic
;
new_extra
->
next
=
*
extra_meta
;
*
extra_meta
=
new_extra
;
return
;
...
...
@@ -498,13 +508,14 @@ fail:
typedef
struct
ID3v2EMFunc
{
const
char
*
tag3
;
const
char
*
tag4
;
void
(
*
read
)(
AVFormatContext
*
,
AVIOContext
*
,
int
,
char
*
,
ID3v2ExtraMeta
**
);
void
(
*
read
)(
AVFormatContext
*
,
AVIOContext
*
,
int
,
char
*
,
ID3v2ExtraMeta
**
);
void
(
*
free
)(
void
*
obj
);
}
ID3v2EMFunc
;
static
const
ID3v2EMFunc
id3v2_extra_meta_funcs
[]
=
{
{
"GEO"
,
"GEOB"
,
read_geobtag
,
free_geobtag
},
{
"PIC"
,
"APIC"
,
read_apic
,
free_apic
},
{
"PIC"
,
"APIC"
,
read_apic
,
free_apic
},
{
NULL
}
};
...
...
@@ -538,7 +549,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
AVIOContext
pb
;
AVIOContext
*
pbx
;
unsigned
char
*
buffer
=
NULL
;
int
buffer_size
=
0
;
int
buffer_size
=
0
;
const
ID3v2EMFunc
*
extra_func
;
switch
(
version
)
{
...
...
@@ -547,13 +558,13 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
reason
=
"compression"
;
goto
error
;
}
isv34
=
0
;
isv34
=
0
;
taghdrlen
=
6
;
break
;
case
3
:
case
4
:
isv34
=
1
;
isv34
=
1
;
taghdrlen
=
10
;
break
;
...
...
@@ -567,7 +578,8 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
if
(
isv34
&&
flags
&
0x40
)
{
/* Extended header present, just skip over it */
int
extlen
=
get_size
(
s
->
pb
,
4
);
if
(
version
==
4
)
extlen
-=
4
;
// in v2.4 the length includes the length field we just read
/* In v2.4 the length includes the length field we just read. */
extlen
-=
4
;
if
(
extlen
<
0
)
{
reason
=
"invalid extended header length"
;
...
...
@@ -578,24 +590,26 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
while
(
len
>=
taghdrlen
)
{
unsigned
int
tflags
=
0
;
int
tunsync
=
0
;
int
tunsync
=
0
;
if
(
isv34
)
{
avio_read
(
s
->
pb
,
tag
,
4
);
tag
[
4
]
=
0
;
if
(
version
==
3
)
{
if
(
version
==
3
)
{
tlen
=
avio_rb32
(
s
->
pb
);
}
else
}
else
tlen
=
get_size
(
s
->
pb
,
4
);
tflags
=
avio_rb16
(
s
->
pb
);
tflags
=
avio_rb16
(
s
->
pb
);
tunsync
=
tflags
&
ID3v2_FLAG_UNSYNCH
;
}
else
{
avio_read
(
s
->
pb
,
tag
,
3
);
tag
[
3
]
=
0
;
tlen
=
avio_rb24
(
s
->
pb
);
tlen
=
avio_rb24
(
s
->
pb
);
}
if
(
tlen
<
0
||
tlen
>
len
-
taghdrlen
)
{
av_log
(
s
,
AV_LOG_WARNING
,
"Invalid size in frame %s, skipping the rest of tag.
\n
"
,
tag
);
av_log
(
s
,
AV_LOG_WARNING
,
"Invalid size in frame %s, skipping the rest of tag.
\n
"
,
tag
);
break
;
}
len
-=
taghdrlen
+
tlen
;
...
...
@@ -603,7 +617,8 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
if
(
!
tlen
)
{
if
(
tag
[
0
])
av_log
(
s
,
AV_LOG_DEBUG
,
"Invalid empty frame %s, skipping.
\n
"
,
tag
);
av_log
(
s
,
AV_LOG_DEBUG
,
"Invalid empty frame %s, skipping.
\n
"
,
tag
);
continue
;
}
...
...
@@ -613,10 +628,13 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
}
if
(
tflags
&
(
ID3v2_FLAG_ENCRYPTION
|
ID3v2_FLAG_COMPRESSION
))
{
av_log
(
s
,
AV_LOG_WARNING
,
"Skipping encrypted/compressed ID3v2 frame %s.
\n
"
,
tag
);
av_log
(
s
,
AV_LOG_WARNING
,
"Skipping encrypted/compressed ID3v2 frame %s.
\n
"
,
tag
);
avio_skip
(
s
->
pb
,
tlen
);
/* check for text tag or supported special meta tag */
}
else
if
(
tag
[
0
]
==
'T'
||
(
extra_meta
&&
(
extra_func
=
get_extra_meta_func
(
tag
,
isv34
))))
{
}
else
if
(
tag
[
0
]
==
'T'
||
(
extra_meta
&&
(
extra_func
=
get_extra_meta_func
(
tag
,
isv34
))))
{
if
(
unsync
||
tunsync
)
{
int64_t
end
=
avio_tell
(
s
->
pb
)
+
tlen
;
uint8_t
*
b
;
...
...
@@ -633,9 +651,10 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
*
b
++
=
val
?
val
:
avio_r8
(
s
->
pb
);
}
}
ffio_init_context
(
&
pb
,
buffer
,
b
-
buffer
,
0
,
NULL
,
NULL
,
NULL
,
NULL
);
ffio_init_context
(
&
pb
,
buffer
,
b
-
buffer
,
0
,
NULL
,
NULL
,
NULL
,
NULL
);
tlen
=
b
-
buffer
;
pbx
=
&
pb
;
// read from sync buffer
pbx
=
&
pb
;
// read from sync buffer
}
else
{
pbx
=
s
->
pb
;
// read straight from input
}
...
...
@@ -645,8 +664,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
else
/* parse special meta tag */
extra_func
->
read
(
s
,
pbx
,
tlen
,
tag
,
extra_meta
);
}
else
if
(
!
tag
[
0
])
{
}
else
if
(
!
tag
[
0
])
{
if
(
tag
[
1
])
av_log
(
s
,
AV_LOG_WARNING
,
"invalid frame id, assuming padding"
);
avio_skip
(
s
->
pb
,
tlen
);
...
...
@@ -657,22 +675,25 @@ seek:
avio_seek
(
s
->
pb
,
next
,
SEEK_SET
);
}
if
(
version
==
4
&&
flags
&
0x10
)
/* Footer preset, always 10 bytes, skip over it */
/* Footer preset, always 10 bytes, skip over it */
if
(
version
==
4
&&
flags
&
0x10
)
end
+=
10
;
error:
error:
if
(
reason
)
av_log
(
s
,
AV_LOG_INFO
,
"ID3v2.%d tag skipped, cannot handle %s
\n
"
,
version
,
reason
);
av_log
(
s
,
AV_LOG_INFO
,
"ID3v2.%d tag skipped, cannot handle %s
\n
"
,
version
,
reason
);
avio_seek
(
s
->
pb
,
end
,
SEEK_SET
);
av_free
(
buffer
);
return
;
}
void
ff_id3v2_read
(
AVFormatContext
*
s
,
const
char
*
magic
,
ID3v2ExtraMeta
**
extra_meta
)
void
ff_id3v2_read
(
AVFormatContext
*
s
,
const
char
*
magic
,
ID3v2ExtraMeta
**
extra_meta
)
{
int
len
,
ret
;
uint8_t
buf
[
ID3v2_HEADER_SIZE
];
int
found_header
;
int
found_header
;
int64_t
off
;
do
{
...
...
@@ -681,8 +702,8 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra
ret
=
avio_read
(
s
->
pb
,
buf
,
ID3v2_HEADER_SIZE
);
if
(
ret
!=
ID3v2_HEADER_SIZE
)
break
;
found_header
=
ff_id3v2_match
(
buf
,
magic
);
if
(
found_header
)
{
found_header
=
ff_id3v2_match
(
buf
,
magic
);
if
(
found_header
)
{
/* parse ID3v2 header */
len
=
((
buf
[
6
]
&
0x7f
)
<<
21
)
|
((
buf
[
7
]
&
0x7f
)
<<
14
)
|
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment