1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-28 20:53:54 +02:00

mov: Implement spatial audio support

As defined by Google's Spatial Audio RFC.

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
Vittorio Giovara 2017-05-02 09:58:37 -04:00 committed by James Almer
parent e6358ec1ac
commit 6f8b8e6332

View File

@ -7334,6 +7334,100 @@ cleanup:
return ret;
}
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
int i, version, type;
int ambisonic_order, channel_order, normalization, channel_count;
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
if (atom.size < 16) {
av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
return AVERROR_INVALIDDATA;
}
version = avio_r8(pb);
if (version) {
av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
return 0;
}
type = avio_r8(pb);
if (type) {
av_log(c->fc, AV_LOG_WARNING,
"Unsupported ambisonic type %d\n", type);
return 0;
}
ambisonic_order = avio_rb32(pb);
channel_order = avio_r8(pb);
if (channel_order) {
av_log(c->fc, AV_LOG_WARNING,
"Unsupported channel_order %d\n", channel_order);
return 0;
}
normalization = avio_r8(pb);
if (normalization) {
av_log(c->fc, AV_LOG_WARNING,
"Unsupported normalization %d\n", normalization);
return 0;
}
channel_count = avio_rb32(pb);
if (channel_count != (ambisonic_order + 1) * (ambisonic_order + 1)) {
av_log(c->fc, AV_LOG_ERROR,
"Invalid number of channels (%d / %d)\n",
channel_count, ambisonic_order);
return 0;
}
for (i = 0; i < channel_count; i++) {
if (i != avio_rb32(pb)) {
av_log(c->fc, AV_LOG_WARNING,
"Ambisonic channel reordering is not supported\n");
return 0;
}
}
av_channel_layout_uninit(&st->codecpar->ch_layout);
st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_AMBISONIC;
st->codecpar->ch_layout.nb_channels = channel_count;
return 0;
}
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
int version;
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
if (atom.size < 5) {
av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
return AVERROR_INVALIDDATA;
}
version = avio_r8(pb);
if (version) {
av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
return 0;
}
st->disposition |= AV_DISPOSITION_NON_DIEGETIC;
return 0;
}
static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('A','C','L','R'), mov_read_aclr },
{ MKTAG('A','P','R','G'), mov_read_avid },
@ -7434,6 +7528,8 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
{ MKTAG('k','i','n','d'), mov_read_kind },
{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
{ 0, NULL }
};