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) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel