mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-25 16:52:31 +00:00
apetag: add support for writing APE tags
This will be useful in the WavPack muxer.
This commit is contained in:
parent
01656fd476
commit
88de0c7901
@ -23,12 +23,14 @@
|
|||||||
#include "libavutil/intreadwrite.h"
|
#include "libavutil/intreadwrite.h"
|
||||||
#include "libavutil/dict.h"
|
#include "libavutil/dict.h"
|
||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
|
#include "avio_internal.h"
|
||||||
#include "apetag.h"
|
#include "apetag.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define APE_TAG_VERSION 2000
|
#define APE_TAG_VERSION 2000
|
||||||
#define APE_TAG_FOOTER_BYTES 32
|
#define APE_TAG_FOOTER_BYTES 32
|
||||||
#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31)
|
#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_HEADER (1 << 29)
|
||||||
#define APE_TAG_FLAG_IS_BINARY (1 << 1)
|
#define APE_TAG_FLAG_IS_BINARY (1 << 1)
|
||||||
|
|
||||||
@ -169,3 +171,57 @@ int64_t ff_ape_parse_tag(AVFormatContext *s)
|
|||||||
|
|
||||||
return tag_start;
|
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;
|
||||||
|
}
|
||||||
|
@ -32,4 +32,9 @@
|
|||||||
*/
|
*/
|
||||||
int64_t ff_ape_parse_tag(AVFormatContext *s);
|
int64_t ff_ape_parse_tag(AVFormatContext *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an APE tag into a file.
|
||||||
|
*/
|
||||||
|
int ff_ape_write_tag(AVFormatContext *s);
|
||||||
|
|
||||||
#endif /* AVFORMAT_APETAG_H */
|
#endif /* AVFORMAT_APETAG_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user