summaryrefslogtreecommitdiff
path: root/libavformat/id3v2enc.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-02-27 22:08:50 +0100
committerAnton Khirnov <anton@khirnov.net>2012-02-29 14:26:14 +0100
commit411225aabce57411d1544a7bbc6f6bee6d8ef638 (patch)
treef3dcc31c02aaf9507f369239950c7c8349248b07 /libavformat/id3v2enc.c
parentc19981774880919c7f9417014bdcb1fb63f69231 (diff)
id3v2enc: split ff_id3v2_write().
This will allow writing the tag in several steps, needed for writing attached pictures.
Diffstat (limited to 'libavformat/id3v2enc.c')
-rw-r--r--libavformat/id3v2enc.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index 3a4d229232..8666818128 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -97,50 +97,70 @@ static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const
return -1;
}
-int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version,
- const char *magic)
+void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
+ const char *magic)
{
- int64_t size_pos, cur_pos;
- AVDictionaryEntry *t = NULL;
-
- int totlen = 0, enc = id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM :
- ID3v2_ENCODING_UTF8;
+ id3->version = id3v2_version;
-
- avio_wb32(s->pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version));
- avio_w8(s->pb, 0);
- avio_w8(s->pb, 0); /* flags */
+ avio_wb32(pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version));
+ avio_w8(pb, 0);
+ avio_w8(pb, 0); /* flags */
/* reserve space for size */
- size_pos = avio_tell(s->pb);
- avio_wb32(s->pb, 0);
+ id3->size_pos = avio_tell(pb);
+ avio_wb32(pb, 0);
+}
+
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+{
+ AVDictionaryEntry *t = NULL;
+ int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
+ ID3v2_ENCODING_UTF8;
ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
- if (id3v2_version == 4)
+ if (id3->version == 4)
ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
int ret;
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
- totlen += ret;
+ id3->len += ret;
continue;
}
- if ((ret = id3v2_check_write_tag(s, t, id3v2_version == 3 ?
+ if ((ret = id3v2_check_write_tag(s, t, id3->version == 3 ?
ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
- totlen += ret;
+ id3->len += ret;
continue;
}
/* unknown tag, write as TXXX frame */
if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
return ret;
- totlen += ret;
+ id3->len += ret;
}
- cur_pos = avio_tell(s->pb);
- avio_seek(s->pb, size_pos, SEEK_SET);
- id3v2_put_size(s->pb, totlen);
- avio_seek(s->pb, cur_pos, SEEK_SET);
+ return 0;
+}
+
+void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb)
+{
+ int64_t cur_pos = avio_tell(pb);
+ avio_seek(pb, id3->size_pos, SEEK_SET);
+ id3v2_put_size(pb, id3->len);
+ avio_seek(pb, cur_pos, SEEK_SET);
+}
+
+int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version,
+ const char *magic)
+{
+ ID3v2EncContext id3 = { 0 };
+ int ret;
+
+ ff_id3v2_start(&id3, s->pb, id3v2_version, magic);
+ if ((ret = ff_id3v2_write_metadata(s, &id3)) < 0)
+ return ret;
+ ff_id3v2_finish(&id3, s->pb);
+
return 0;
}