[FFmpeg-devel] [PATCH 279/279] mov: Implement spatial audio support
James Almer
jamrial at gmail.com
Wed Dec 8 03:06:49 EET 2021
From: Vittorio Giovara <vittorio.giovara at gmail.com>
As defined by Google's Spatial Audio RFC.
Signed-off-by: Vittorio Giovara <vittorio.giovara at gmail.com>
Signed-off-by: Anton Khirnov <anton at khirnov.net>
Signed-off-by: James Almer <jamrial at gmail.com>
---
libavformat/mov.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/libavformat/mov.c b/libavformat/mov.c
index b061659252..9bb126e028 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7223,6 +7223,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 },
@@ -7322,6 +7416,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 }
};
--
2.34.1
More information about the ffmpeg-devel
mailing list