---
libavformat/wav.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 69 insertions(+), 1 deletions(-)
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 298880d..3147093 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -378,6 +378,66 @@ static const AVMetadataConv wav_metadata_conv[] = {
{0},
};
+static const AVMetadataConv wav_info_tag_conv[] = {
+ {"IART", "artist" },
+ {"ICMT", "comment" },
+ {"ICOP", "copyright" },
+ {"ICRD", "creation_date"},
+ {"IGNR", "genre" },
+ {"INAM", "title" },
+ {"ISFT", "encoder" },
+ {0},
+};
+
+static int wav_parse_info_tags(AVFormatContext *s, int64_t size,
AVStream **stream)
+{
+ int64_t start, end, cur;
+ AVIOContext *pb = s->pb;
+
+ start = avio_tell(pb);
+ end = start + size;
+
+ while ( (cur = avio_tell(pb)) < end) {
+ unsigned int chunk_code;
+ int64_t chunk_size;
+ char *key, *value;
+
+ chunk_size = next_tag(pb, &chunk_code);
+ if (chunk_size > end || end - chunk_size < cur) {
+ av_log(s, AV_LOG_ERROR, "too big INFO subchunk\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ key = av_malloc(4 + 1);
+ value = av_malloc(chunk_size + 1);
+ if (!key || !value) {
+ av_log(s, AV_LOG_ERROR, "out of memory, unable to read
INFO tag\n");
+ return AVERROR(ENOMEM);
+ }
+
+#ifdef HAVE_BIG_ENDIAN
+ chunk_code = av_bswap32(chunk_code);
+#endif
+ snprintf( key, 5, "%4.4s", &chunk_code );
+
+ if (avio_read(pb, value, chunk_size) != chunk_size) {
+ av_freep(key);
+ av_freep(value);
+ av_log(s, AV_LOG_ERROR, "premature end of file while
reading INFO tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ key[4] = '\0';
+ value[chunk_size] = '\0';
+
+ av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
+ }
+
+ ff_metadata_conv_ctx(s, NULL, wav_info_tag_conv);
+
+ return 0;
+}
+
/* wav input */
static int wav_read_header(AVFormatContext *s,
AVFormatParameters *ap)
@@ -385,7 +445,7 @@ static int wav_read_header(AVFormatContext *s,
int64_t size, av_uninit(data_size);
int64_t sample_count=0;
int rf64;
- unsigned int tag;
+ unsigned int tag, list_type;
AVIOContext *pb = s->pb;
AVStream *st;
WAVContext *wav = s->priv_data;
@@ -467,6 +527,14 @@ static int wav_read_header(AVFormatContext *s,
if ((ret = wav_parse_bext_tag(s, size)) < 0)
return ret;
break;
+ case MKTAG('L', 'I', 'S', 'T'):
+ list_type = avio_rl32(pb);
+ switch (list_type) {
+ case MKTAG('I', 'N', 'F', 'O'):
+ if ((ret = wav_parse_info_tags(s, size - 4, &st)) < 0)
+ return ret;
+ }
+ break;
}
/* seek to next tag unless we know that we'll run into EOF */
--
1.7.5.4
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel