mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-18 05:24:42 +00:00
Merge commit '9a07fac678a8540d076e635061bbaa4ed09a9431'
* commit '9a07fac678a8540d076e635061bbaa4ed09a9431':
mov: read hydrogenaudio replaygain information
Conflicts:
libavformat/Makefile
libavformat/mov.c
See: 37a15f3e66
Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
6e573b7759
@ -220,7 +220,7 @@ OBJS-$(CONFIG_MLP_MUXER) += rawenc.o
|
|||||||
OBJS-$(CONFIG_MM_DEMUXER) += mm.o
|
OBJS-$(CONFIG_MM_DEMUXER) += mm.o
|
||||||
OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o
|
OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o
|
||||||
OBJS-$(CONFIG_MMF_MUXER) += mmf.o rawenc.o
|
OBJS-$(CONFIG_MMF_MUXER) += mmf.o rawenc.o
|
||||||
OBJS-$(CONFIG_MOV_DEMUXER) += mov.o isom.o mov_chan.o
|
OBJS-$(CONFIG_MOV_DEMUXER) += mov.o isom.o mov_chan.o replaygain.o
|
||||||
OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o hevc.o \
|
OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o hevc.o \
|
||||||
movenchint.o mov_chan.o rtp.o
|
movenchint.o mov_chan.o rtp.o
|
||||||
OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o id3v2enc.o
|
OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o id3v2enc.o
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "libavcodec/get_bits.h"
|
#include "libavcodec/get_bits.h"
|
||||||
#include "id3v1.h"
|
#include "id3v1.h"
|
||||||
#include "mov_chan.h"
|
#include "mov_chan.h"
|
||||||
|
#include "replaygain.h"
|
||||||
|
|
||||||
#if CONFIG_ZLIB
|
#if CONFIG_ZLIB
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@ -2508,6 +2509,88 @@ static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
return ret;
|
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)
|
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||||
{
|
{
|
||||||
while (atom.size > 8) {
|
while (atom.size > 8) {
|
||||||
@ -3051,6 +3134,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
|
|||||||
{ MKTAG('h','v','c','C'), mov_read_glbl },
|
{ MKTAG('h','v','c','C'), mov_read_glbl },
|
||||||
{ MKTAG('u','u','i','d'), mov_read_uuid },
|
{ MKTAG('u','u','i','d'), mov_read_uuid },
|
||||||
{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
|
{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
|
||||||
|
{ MKTAG('-','-','-','-'), mov_read_custom },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3509,6 +3593,19 @@ static int mov_read_header(AVFormatContext *s)
|
|||||||
|
|
||||||
ff_rfps_calculate(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user