[FFmpeg-devel] [PATCH] lavf: Make id3v1_create_tag a lavf internal function
James Almer
jamrial at gmail.com
Sat Jul 13 20:37:51 CEST 2013
There are more containers than just mp3 with support for id3v1,
and we currently have muxer for at least one of them
Signed-off-by: James Almer <jamrial at gmail.com>
---
libavformat/Makefile | 3 ++-
libavformat/id3v1.h | 6 +++++
libavformat/id3v1enc.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
libavformat/mp3enc.c | 52 ++++-------------------------------
4 files changed, 86 insertions(+), 48 deletions(-)
create mode 100644 libavformat/id3v1enc.c
diff --git a/libavformat/Makefile b/libavformat/Makefile
index cc4a4cb..2c59b1d 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -215,7 +215,8 @@ OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o \
movenchint.o mov_chan.o rtp.o
OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o id3v2enc.o
OBJS-$(CONFIG_MP3_DEMUXER) += mp3dec.o
-OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o id3v2enc.o
+OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o id3v1enc.o \
+ id3v2enc.o
OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o apetag.o img2.o
OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o apetag.o img2.o
OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o
diff --git a/libavformat/id3v1.h b/libavformat/id3v1.h
index d5dca35..daf5315 100644
--- a/libavformat/id3v1.h
+++ b/libavformat/id3v1.h
@@ -23,6 +23,7 @@
#define AVFORMAT_ID3V1_H
#include "avformat.h"
+#include "metadata.h"
#define ID3v1_TAG_SIZE 128
@@ -38,4 +39,9 @@ extern const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1];
*/
void ff_id3v1_read(AVFormatContext *s);
+/**
+ * Write an ID3v1 tag
+ */
+int ff_id3v1_write(AVFormatContext *s);
+
#endif /* AVFORMAT_ID3V1_H */
diff --git a/libavformat/id3v1enc.c b/libavformat/id3v1enc.c
new file mode 100644
index 0000000..9b7b6a7
--- /dev/null
+++ b/libavformat/id3v1enc.c
@@ -0,0 +1,73 @@
+/*
+ * ID3v1 header writer
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
+#include "id3v1.h"
+
+static int set_string(AVFormatContext *s, const char *key,
+ uint8_t *buf, int buf_size)
+{
+ AVDictionaryEntry *tag;
+ if ((tag = av_dict_get(s->metadata, key, NULL, 0)))
+ av_strlcpy(buf, tag->value, buf_size);
+ return !!tag;
+}
+
+int ff_id3v1_write(AVFormatContext *s)
+{
+ AVDictionaryEntry *tag;
+ uint8_t buf[ID3v1_TAG_SIZE];
+ int i, count = 0;
+
+ memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
+ buf[0] = 'T';
+ buf[1] = 'A';
+ buf[2] = 'G';
+ /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */
+ count += set_string(s, "title", buf + 3, 30 + 1);
+ count += set_string(s, "artist", buf + 33, 30 + 1);
+ count += set_string(s, "album", buf + 63, 30 + 1);
+ count += set_string(s, "date", buf + 93, 4 + 1);
+ count += set_string(s, "comment", buf + 97, 30 + 1);
+ if ((tag = av_dict_get(s->metadata, "track", NULL, 0))) {
+ buf[125] = 0;
+ buf[126] = atoi(tag->value);
+ count++;
+ }
+ buf[127] = 0xFF; /* default to unknown genre */
+ if ((tag = av_dict_get(s->metadata, "genre", NULL, 0))) {
+ for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
+ if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
+ buf[127] = i;
+ count++;
+ break;
+ }
+ }
+ }
+ if (!count)
+ return -1;
+
+ avio_write(s->pb, buf, ID3v1_TAG_SIZE);
+
+ return 0;
+}
+
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index ee0956e..b2b5fad 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -24,7 +24,6 @@
#include "id3v1.h"
#include "id3v2.h"
#include "rawenc.h"
-#include "libavutil/avstring.h"
#include "libavcodec/mpegaudio.h"
#include "libavcodec/mpegaudiodata.h"
#include "libavcodec/mpegaudiodecheader.h"
@@ -34,51 +33,8 @@
#include "libavcodec/mpegaudiodata.h"
#include "libavcodec/mpegaudiodecheader.h"
#include "libavformat/avio_internal.h"
-#include "libavutil/dict.h"
#include "libavutil/avassert.h"
-static int id3v1_set_string(AVFormatContext *s, const char *key,
- uint8_t *buf, int buf_size)
-{
- AVDictionaryEntry *tag;
- if ((tag = av_dict_get(s->metadata, key, NULL, 0)))
- av_strlcpy(buf, tag->value, buf_size);
- return !!tag;
-}
-
-static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
-{
- AVDictionaryEntry *tag;
- int i, count = 0;
-
- memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
- buf[0] = 'T';
- buf[1] = 'A';
- buf[2] = 'G';
- /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */
- count += id3v1_set_string(s, "TIT2", buf + 3, 30 + 1); //title
- count += id3v1_set_string(s, "TPE1", buf + 33, 30 + 1); //author|artist
- count += id3v1_set_string(s, "TALB", buf + 63, 30 + 1); //album
- count += id3v1_set_string(s, "TDRL", buf + 93, 4 + 1); //date
- count += id3v1_set_string(s, "comment", buf + 97, 30 + 1);
- if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
- buf[125] = 0;
- buf[126] = atoi(tag->value);
- count++;
- }
- 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])) {
- buf[127] = i;
- count++;
- break;
- }
- }
- }
- return count;
-}
-
#define XING_NUM_BAGS 400
#define XING_TOC_SIZE 100
// maximum size of the xing frame: offset/Xing/flags/frames/size/TOC
@@ -349,7 +305,6 @@ static void mp3_update_xing(AVFormatContext *s)
static int mp3_write_trailer(struct AVFormatContext *s)
{
- uint8_t buf[ID3v1_TAG_SIZE];
MP3Context *mp3 = s->priv_data;
if (mp3->pics_to_write) {
@@ -359,8 +314,11 @@ static int mp3_write_trailer(struct AVFormatContext *s)
}
/* write the id3v1 tag */
- if (mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
- avio_write(s->pb, buf, ID3v1_TAG_SIZE);
+ if (mp3->write_id3v1) {
+ /* recover the generic tags */
+ ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv);
+ ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv);
+ ff_id3v1_write(s);
}
if (mp3->xing_offset)
--
1.8.1.5
More information about the ffmpeg-devel
mailing list