[FFmpeg-devel] [PATCH] mov: add channel label support
Courtland Idstrom
cidstrom at telltalegames.com
Sat Mar 17 04:29:34 EET 2018
Adds the ability to support writing channel labels to mov files if the layout_tag fails, instead of printing a warning and skipping the tag. This fixes channels such as DL/DR, which will now write to LeftTotal/RightTotal instead of omitting the channel tag.
---
Changelog | 1 +
libavformat/mov_chan.c | 20 ++++++++++++++++++++
libavformat/mov_chan.h | 8 ++++++++
libavformat/movenc.c | 38 +++++++++++++++++++++++++++++++-------
4 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/Changelog b/Changelog
index 32a93d916a..d9b46b6d78 100644
--- a/Changelog
+++ b/Changelog
@@ -48,6 +48,7 @@ version <next>:
- drmeter audio filter
- hapqa_extract bitstream filter
- movenc option to write track title metadata
+- mov: write channel labels if channel layout is not found
version 3.4:
- deflicker video filter
diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
index 324dd5f913..4eb434a97b 100644
--- a/libavformat/mov_chan.c
+++ b/libavformat/mov_chan.c
@@ -478,6 +478,26 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
return layout_map[i].layout;
}
+uint32_t ff_mov_get_channel_label_tag(uint64_t channel)
+{
+ int i;
+
+ if(channel == 0)
+ return 0;
+
+ for(i=0; i<=17; ++i)
+ if((1U << i) & channel)
+ return i+1;
+
+ if(channel == AV_CH_STEREO_LEFT)
+ return 38; // LeftTotal
+
+ if(channel == AV_CH_STEREO_RIGHT)
+ return 39; // RightTotal
+
+ return 0;
+}
+
static uint32_t mov_get_channel_label(uint32_t label)
{
if (label == 0)
diff --git a/libavformat/mov_chan.h b/libavformat/mov_chan.h
index ca28345aef..81acb73655 100644
--- a/libavformat/mov_chan.h
+++ b/libavformat/mov_chan.h
@@ -53,6 +53,14 @@ uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id,
uint64_t channel_layout,
uint32_t *bitmap);
+/**
+ * Get the channel label tag for the specified channel.
+ *
+ * @param[in] channel channel identifier
+ * @return channel label tag
+ */
+uint32_t ff_mov_get_channel_label_tag(uint64_t channel);
+
/**
* Read 'chan' tag from the input stream.
*
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index ea48c3293e..2c79462e9f 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -742,30 +742,54 @@ static int mov_write_dops_tag(AVIOContext *pb, MOVTrack *track)
return update_size(pb, pos);
}
+static void mov_write_channel_layout_label_tags(AVFormatContext *s, AVIOContext *pb, uint64_t channel_layout)
+{
+ int i, channels;
+
+ channels = av_get_channel_layout_nb_channels(channel_layout);
+
+ for(i=0; i<channels; ++i)
+ {
+ int32_t channel, channel_label_tag;
+
+ channel = av_channel_layout_extract_channel(channel_layout, i);
+ channel_label_tag = ff_mov_get_channel_label_tag(channel);
+
+ av_log(s, AV_LOG_WARNING, "label[%d] = %d\n", i, channel_label_tag);
+
+ avio_wb32(pb, channel_label_tag); // mChannelLabel
+ avio_wb32(pb, 0); // mChannelFlags
+ avio_wb32(pb, 0); // mCoordinates[0]
+ avio_wb32(pb, 0); // mCoordinates[1]
+ avio_wb32(pb, 0); // mCoordinates[2]
+ }
+}
+
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
{
- uint32_t layout_tag, bitmap;
+ uint32_t layout_tag, bitmap, num_channel_desc;
int64_t pos = avio_tell(pb);
layout_tag = ff_mov_get_channel_layout_tag(track->par->codec_id,
track->par->channel_layout,
&bitmap);
- if (!layout_tag) {
- av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
- "lack of channel information\n");
- return 0;
- }
if (track->multichannel_as_mono)
return 0;
+ num_channel_desc = layout_tag == 0 ? av_get_channel_layout_nb_channels(track->par->channel_layout) : 0;
+
avio_wb32(pb, 0); // Size
ffio_wfourcc(pb, "chan"); // Type
avio_w8(pb, 0); // Version
avio_wb24(pb, 0); // Flags
avio_wb32(pb, layout_tag); // mChannelLayoutTag
avio_wb32(pb, bitmap); // mChannelBitmap
- avio_wb32(pb, 0); // mNumberChannelDescriptions
+ avio_wb32(pb, num_channel_desc); // mNumberChannelDescriptions
+
+ if(!layout_tag) {
+ mov_write_channel_layout_label_tags(s, pb, track->par->channel_layout);
+ }
return update_size(pb, pos);
}
--
2.14.3 (Apple Git-98)
More information about the ffmpeg-devel
mailing list