PR #21240 opened by nyh163925
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21240
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21240.patch
Disabled by --disable-id3, default enabled.
Turning off ID3 support when it is clear that the ID3
protocol is not needed can save approximately 11kb of
code size.
>From 7ba25a716484b4bd57cdbe35eabae8eee70a4686 Mon Sep 17 00:00:00 2001
From: niyinghao <[email protected]>
Date: Fri, 19 Dec 2025 20:57:10 +0800
Subject: [PATCH] avformat/id3: Add macro control ID3 protocol enable
Disabled by --disable-id3, default enabled.
Turning off ID3 support when it is clear that the ID3
protocol is not needed can save approximately 11kb of
code size.
---
configure | 2 +
libavformat/id3v1.c | 22 +++++++++-
libavformat/id3v1.h | 2 +-
libavformat/id3v2.c | 99 +++++++++++++++++++++++++++++++++++++++++-
libavformat/id3v2enc.c | 26 +++++++++++
libavformat/mov.c | 6 ++-
libavformat/mp3enc.c | 6 ++-
7 files changed, 156 insertions(+), 7 deletions(-)
diff --git a/configure b/configure
index 9458a1d964..69a61f8004 100755
--- a/configure
+++ b/configure
@@ -2101,6 +2101,7 @@ FEATURE_LIST="
ftrapv
gray
hardcoded_tables
+ id3
omx_rpi
runtime_cpudetect
safe_bitstream_reader
@@ -4294,6 +4295,7 @@ enable debug
enable doc
enable faan faandct faanidct
enable iamf
+enable id3
enable large_tests
enable optimizations
enable ptx_compression
diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c
index 3189a48b8c..84c5a33108 100644
--- a/libavformat/id3v1.c
+++ b/libavformat/id3v1.c
@@ -20,10 +20,12 @@
*/
#include "id3v1.h"
+
+#if CONFIG_ID3
#include "libavutil/dict.h"
/* See Genre List at http://id3.org/id3v2.3.0 */
-const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
+const char * const id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
[0] = "Blues",
[1] = "Classic Rock",
[2] = "Country",
@@ -218,6 +220,11 @@ const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1]
= {
[191] = "Psybient"
};
+const char *ff_id3v1_genre_str(int genre)
+{
+ return (genre < 0 || genre > ID3v1_GENRE_MAX) ? NULL :
id3v1_genre_str[genre];
+}
+
static void get_string(AVFormatContext *s, const char *key,
const uint8_t *buf, int buf_size)
{
@@ -271,7 +278,7 @@ static int parse_tag(AVFormatContext *s, const uint8_t *buf)
}
genre = buf[127];
if (genre <= ID3v1_GENRE_MAX)
- av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0);
+ av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str(genre), 0);
return 0;
}
@@ -294,3 +301,14 @@ void ff_id3v1_read(AVFormatContext *s)
}
}
}
+#else
+
+void ff_id3v1_read(AVFormatContext *s)
+{
+}
+
+const char *ff_id3v1_genre_str(int genre)
+{
+ return NULL;
+}
+#endif
diff --git a/libavformat/id3v1.h b/libavformat/id3v1.h
index b3ad16df6c..837c19db58 100644
--- a/libavformat/id3v1.h
+++ b/libavformat/id3v1.h
@@ -31,7 +31,7 @@
/**
* ID3v1 genres
*/
-extern const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1];
+const char *ff_id3v1_genre_str(int genre);
/**
* Read an ID3v1 tag
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 9d4a9802a9..806538d41c 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -28,6 +28,7 @@
#include "config.h"
+#if CONFIG_ID3
#if CONFIG_ZLIB
#include <zlib.h>
#endif
@@ -142,6 +143,10 @@ const CodecMime ff_id3v2_mime_tags[] = {
{ "PNG", AV_CODEC_ID_PNG }, /* ID3v2.2 */
{ "", AV_CODEC_ID_NONE },
};
+#else
+#include "avio_internal.h"
+#include "id3v2.h"
+#endif
int ff_id3v2_match(const uint8_t *buf, const char *magic)
{
@@ -168,6 +173,7 @@ int ff_id3v2_tag_len(const uint8_t *buf)
return len;
}
+#if CONFIG_ID3
static unsigned int get_size(AVIOContext *s, int len)
{
int v = 0;
@@ -351,7 +357,7 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb,
int taglen,
(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]);
+ dst = av_strdup(ff_id3v1_genre_str(genre));
} else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
/* dst now contains the key, need to get value */
key = dst;
@@ -1266,3 +1272,94 @@ int ff_id3v2_parse_priv(AVFormatContext *s,
ID3v2ExtraMeta *extra_meta)
{
return ff_id3v2_parse_priv_dict(&s->metadata, extra_meta);
}
+
+#else
+
+static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
+ AVFormatContext *s, const char *magic,
+ ID3v2ExtraMeta **extra_metap, int64_t
max_search_size)
+{
+ uint8_t buf[ID3v2_HEADER_SIZE];
+ int len, ret, found_header;
+ int64_t start, off, next;
+
+ if (extra_metap)
+ *extra_metap = NULL;
+
+ if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
+ return;
+
+ start = avio_tell(pb);
+ do {
+ /* save the current offset in case there's nothing to read/skip */
+ off = avio_tell(pb);
+ if (max_search_size && off - start >= max_search_size -
ID3v2_HEADER_SIZE) {
+ avio_seek(pb, off, SEEK_SET);
+ break;
+ }
+
+ ret = ffio_ensure_seekback(pb, ID3v2_HEADER_SIZE);
+ if (ret >= 0)
+ ret = avio_read(pb, buf, ID3v2_HEADER_SIZE);
+
+ if (ret != ID3v2_HEADER_SIZE) {
+ avio_seek(pb, off, SEEK_SET);
+ break;
+ }
+ found_header = ff_id3v2_match(buf, magic);
+ if (found_header) {
+ /* parse ID3v2 header */
+ len = ((buf[6] & 0x7f) << 21) |
+ ((buf[7] & 0x7f) << 14) |
+ ((buf[8] & 0x7f) << 7) |
+ (buf[9] & 0x7f);
+ avio_seek(pb, off + len, SEEK_SET);
+ } else
+ avio_seek(pb, off, SEEK_SET);
+ } while (found_header);
+}
+
+void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char
*magic,
+ ID3v2ExtraMeta **extra_meta)
+{
+ id3v2_read_internal(pb, metadata, NULL, magic, extra_meta, 0);
+}
+
+void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta
**extra_meta,
+ unsigned int max_search_size)
+{
+ id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta,
max_search_size);
+}
+
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
+{
+}
+
+int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
+{
+ return 0;
+}
+
+int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
+{
+ return 0;
+}
+
+int ff_id3v2_parse_priv_dict(AVDictionary **d, ID3v2ExtraMeta *extra_meta)
+{
+ return 0;
+}
+
+int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
+{
+ return 0;
+}
+
+const CodecMime ff_id3v2_mime_tags[] = {
+ { "", AV_CODEC_ID_NONE },
+};
+
+const char * const ff_id3v2_picture_types[] = {
+ "Other",
+};
+#endif
diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index ac907c2758..6bf1b64b52 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -30,6 +30,7 @@
#include "id3v2.h"
#include "mux.h"
+#if CONFIG_ID3
static void id3v2_put_size(AVIOContext *pb, int size)
{
avio_w8(pb, size >> 21 & 0x7f);
@@ -455,3 +456,28 @@ int ff_id3v2_write_simple(struct AVFormatContext *s, int
id3v2_version,
return 0;
}
+#else
+void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
+ const char *magic)
+{
+}
+
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+{
+ return 0;
+}
+
+int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket
*pkt)
+{
+ return 0;
+}
+
+void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb, int padding_bytes)
+{
+}
+
+int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version, const
char *magic)
+{
+ return 0;
+}
+#endif
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 009ddfec80..19a57e3162 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -134,15 +134,17 @@ static int mov_metadata_int8_no_padding(MOVContext *c,
AVIOContext *pb,
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
unsigned len, const char *key)
{
+ const char *gnre;
short genre;
avio_r8(pb); // unknown
genre = avio_r8(pb);
- if (genre < 1 || genre > ID3v1_GENRE_MAX)
+ gnre = ff_id3v1_genre_str(genre - 1);
+ if (genre < 1 || genre > ID3v1_GENRE_MAX || !gnre)
return 0;
c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
- av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
+ av_dict_set(&c->fc->metadata, key, gnre, 0);
return 0;
}
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index 724c7269dc..e3c5db5571 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -52,6 +52,7 @@ static int id3v1_set_string(AVFormatContext *s, const char
*key,
static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
{
AVDictionaryEntry *tag;
+ const char *genre;
int i, count = 0;
memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
@@ -82,7 +83,10 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
buf[127] = 0xFF; /* default to unknown genre */
if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre
for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
- if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
+ if ((genre = ff_id3v1_genre_str(i)) == NULL)
+ break;
+
+ if (!av_strcasecmp(tag->value, genre)) {
buf[127] = i;
count++;
break;
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]