diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-04-10 22:23:40 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-04-10 23:25:15 +0400 |
commit | 6e573b77597c1039667b5d7916551b488aeef828 (patch) | |
tree | b3c7256418744bf78ee5f7e8aac5cc9e9a2d0896 /libavformat/mov.c | |
parent | c486cfab792e53de3f5fc9f5082909ce687a3fe8 (diff) | |
parent | 9a07fac678a8540d076e635061bbaa4ed09a9431 (diff) |
Merge commit '9a07fac678a8540d076e635061bbaa4ed09a9431'
* commit '9a07fac678a8540d076e635061bbaa4ed09a9431':
mov: read hydrogenaudio replaygain information
Conflicts:
libavformat/Makefile
libavformat/mov.c
See: 37a15f3e669372075c88254e070c971aecb485aa
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r-- | libavformat/mov.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index d10bac5678..79bc918cea 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -47,6 +47,7 @@ #include "libavcodec/get_bits.h" #include "id3v1.h" #include "mov_chan.h" +#include "replaygain.h" #if CONFIG_ZLIB #include <zlib.h> @@ -2508,6 +2509,88 @@ static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom) return ret; } +static int mov_read_replaygain(MOVContext *c, AVIOContext *pb, int size) +{ + int64_t end = avio_tell(pb) + size; + uint8_t *key = NULL, *val = NULL; + int i; + + for (i = 0; i < 2; i++) { + uint8_t **p; + uint32_t len, tag; + + if (end - avio_tell(pb) <= 12) + break; + + len = avio_rb32(pb); + tag = avio_rl32(pb); + avio_skip(pb, 4); // flags + + if (len < 12 || len - 12 > end - avio_tell(pb)) + break; + len -= 12; + + if (tag == MKTAG('n', 'a', 'm', 'e')) + p = &key; + else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) { + avio_skip(pb, 4); + len -= 4; + p = &val; + } else + break; + + *p = av_malloc(len + 1); + if (!*p) + break; + avio_read(pb, *p, len); + (*p)[len] = 0; + } + + if (key && val) { + av_dict_set(&c->fc->metadata, key, val, + AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + key = val = NULL; + } + + avio_seek(pb, end, SEEK_SET); + av_freep(&key); + av_freep(&val); + return 0; +} + +static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + int64_t end = avio_tell(pb) + atom.size; + uint32_t tag, len; + + if (atom.size < 8) + goto fail; + + len = avio_rb32(pb); + tag = avio_rl32(pb); + + if (len > atom.size) + goto fail; + + if (tag == MKTAG('m', 'e', 'a', 'n') && len > 12) { + uint8_t domain[128]; + int domain_len; + + avio_skip(pb, 4); // flags + len -= 12; + + domain_len = avio_get_str(pb, len, domain, sizeof(domain)); + avio_skip(pb, len - domain_len); + if (!strcmp(domain, "org.hydrogenaudio.replaygain")) + return mov_read_replaygain(c, pb, end - avio_tell(pb)); + } + +fail: + av_log(c->fc, AV_LOG_VERBOSE, + "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size); + return 0; +} + static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) { while (atom.size > 8) { @@ -3051,6 +3134,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('h','v','c','C'), mov_read_glbl }, { MKTAG('u','u','i','d'), mov_read_uuid }, { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 }, +{ MKTAG('-','-','-','-'), mov_read_custom }, { 0, NULL } }; @@ -3509,6 +3593,19 @@ static int mov_read_header(AVFormatContext *s) ff_rfps_calculate(s); + for (i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + + if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) + continue; + + err = ff_replaygain_export(st, s->metadata); + if (err < 0) { + mov_read_close(s); + return err; + } + } + return 0; } |