diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-05-29 12:19:20 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-05-29 12:40:42 +0400 |
commit | d9cde3976c194688a1f7d16dcb4671eb11422876 (patch) | |
tree | eebba4a91da9261f4cdbb58dbd45b344c3aa0164 /libavformat/apetag.c | |
parent | 53015bb3b340885d576af87afd20479ecb126bf4 (diff) | |
parent | 2d2d6a4883479403798f4ed46941d5b365823570 (diff) |
Merge commit '2d2d6a4883479403798f4ed46941d5b365823570'
* commit '2d2d6a4883479403798f4ed46941d5b365823570':
lavf: add a raw WavPack muxer.
apetag: add support for writing APE tags
matroskaenc: support muxing WavPack
Conflicts:
libavformat/Makefile
libavformat/allformats.c
libavformat/apetag.h
libavformat/version.h
libavformat/wvenc.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/apetag.c')
-rw-r--r-- | libavformat/apetag.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/libavformat/apetag.c b/libavformat/apetag.c index a445c84aef..e74ed26347 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -23,10 +23,12 @@ #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" #include "avformat.h" +#include "avio_internal.h" #include "apetag.h" #include "internal.h" #define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31) +#define APE_TAG_FLAG_CONTAINS_FOOTER (1 << 30) #define APE_TAG_FLAG_IS_HEADER (1 << 29) #define APE_TAG_FLAG_IS_BINARY (1 << 1) @@ -167,3 +169,57 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) return tag_start; } + +int ff_ape_write_tag(AVFormatContext *s) +{ + AVDictionaryEntry *e = NULL; + int64_t start, end; + int size, count = 0; + + if (!s->pb->seekable) + return 0; + + start = avio_tell(s->pb); + + // header + avio_write(s->pb, "APETAGEX", 8); // id + avio_wl32 (s->pb, APE_TAG_VERSION); // version + avio_wl32(s->pb, 0); // reserve space for size + avio_wl32(s->pb, 0); // reserve space for tag count + + // flags + avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER | + APE_TAG_FLAG_IS_HEADER); + ffio_fill(s->pb, 0, 8); // reserved + + while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { + int val_len = strlen(e->value); + + avio_wl32(s->pb, val_len); // value length + avio_wl32(s->pb, 0); // item flags + avio_put_str(s->pb, e->key); // key + avio_write(s->pb, e->value, val_len); // value + count++; + } + + size = avio_tell(s->pb) - start; + + // footer + avio_write(s->pb, "APETAGEX", 8); // id + avio_wl32 (s->pb, APE_TAG_VERSION); // version + avio_wl32(s->pb, size); // size + avio_wl32(s->pb, count); // tag count + + // flags + avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER); + ffio_fill(s->pb, 0, 8); // reserved + + // update values in the header + end = avio_tell(s->pb); + avio_seek(s->pb, start + 12, SEEK_SET); + avio_wl32(s->pb, size); + avio_wl32(s->pb, count); + avio_seek(s->pb, end, SEEK_SET); + + return 0; +} |