[FFmpeg-devel] [PATCH] avformat/mxf: support MCA audio information
Marton Balint
cus at passwd.hu
Sun Nov 7 13:32:20 EET 2021
On Fri, 5 Nov 2021, Marc-Antoine Arnaud wrote:
> ---
> libavformat/mxf.h | 1 +
> libavformat/mxfdec.c | 280 ++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 275 insertions(+), 6 deletions(-)
>
Could you mention in the commit description which
standards/recommendations cover MCA in mxf?
[...]
> @@ -2328,7 +2480,9 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
> AVStream *st;
> FFStream *sti;
> AVTimecode tc;
> + enum AVAudioServiceType *ast;
This declaration can be pushed down to where it is used.
[...]
> + // Soundfield group
> + if (IS_KLV_KEY(mca_sub_descriptor->mca_label_dictionary_id, mxf_soundfield_group)) {
> + MXFSoundfieldGroupUL* group_ptr = (MXFSoundfieldGroupUL*)&mxf_soundfield_groups[0];
const MXFSoundfieldGroupUL *group_ptr = mxf_soundfield_groups;
> +
> + while (group_ptr->uid[0]) {
> + if (IS_KLV_KEY(group_ptr->uid, mca_sub_descriptor->mca_label_dictionary_id)) {
> + st->codecpar->channel_layout = group_ptr->id;
> + break;
> + }
> + group_ptr++;
> + }
> + }
> +
> + // Audio channel
> + if (IS_KLV_KEY(mca_sub_descriptor->mca_label_dictionary_id, mxf_audio_channel)) {
> + MXFChannelOrderingUL* channel_ordering_ptr = (MXFChannelOrderingUL*)&mxf_channel_ordering[0];
const MXFChannelOrderingUL *channel_ordering_ptr = mxf_channel_ordering;
> +
> + while (channel_ordering_ptr->uid[0]) {
> + if (IS_KLV_KEY(channel_ordering_ptr->uid, mca_sub_descriptor->mca_label_dictionary_id)) {
You should check if current_channel < desciptor->channels here, and if
not, then warn the user and break out of the loop. Otherwise
current_channel can grow out of array limits.
It should also be checked that channel_ordering_ptr->index <
descriptor->channels, and if not, then similarly, warn the user and break
out.
Maybe a hard failure (returning AVERROR_INVALIDDATA) is not necessary, to
allow some slightly invalid metadata?
> + source_track->channel_ordering[current_channel] = channel_ordering_ptr->index;
> +
> + if(channel_ordering_ptr->service_type != AV_AUDIO_SERVICE_TYPE_NB) {
> + uint8_t* side_data = av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE, sizeof(*ast));
> + if (!side_data)
> + goto fail_and_free;
> + ast = (enum AVAudioServiceType*)side_data;
> + *ast = channel_ordering_ptr->service_type;
> + }
> +
> + current_channel += 1;
> + break;
> + }
> + channel_ordering_ptr++;
> + }
> + }
> +
[...]
> + source_track->require_reordering = 0;
> + for (j = 0; j < descriptor->channels; ++j) {
> + if (source_track->channel_ordering[j] != j) {
> + source_track->require_reordering = 1;
> + break;
> + }
> + }
If require_reordering == 1 here but either codec is not PCM or
skip_audio_reordering is set then channel_layout should be reset to 0
(unknown). Maybe you should also set require_reordering to 0 in either of
these cases, so further along you no longer have to check codec and
skip_audio_reordering, only require_reordering.
> +
> + if (source_track->require_reordering && is_pcm(st->codecpar->codec_id)) {
> + current_channel = 0;
> + av_log(mxf->fc, AV_LOG_DEBUG, "MCA Audio mapping (");
> + for(j = 0; j < descriptor->channels; ++j) {
> + for(int k = 0; k < descriptor->channels; ++k) {
> + if(source_track->channel_ordering[k] == current_channel) {
> + av_log(mxf->fc, AV_LOG_DEBUG, "%d -> %d", source_track->channel_ordering[k], k);
> + if (current_channel != descriptor->channels - 1)
> + av_log(mxf->fc, AV_LOG_DEBUG, ", ");
> + current_channel += 1;
> + }
> + }
> + }
> + av_log(mxf->fc, AV_LOG_DEBUG, ")\n");
> + }
[...]
> @@ -3920,6 +4185,9 @@ static const AVOption options[] = {
> { "eia608_extract", "extract eia 608 captions from s436m track",
> offsetof(MXFContext, eia608_extract), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
> AV_OPT_FLAG_DECODING_PARAM },
> + { "skip_audio_reordering", "skip audio reordering based on Multi-Channel Audio labelling",
> + offsetof(MXFContext, skip_audio_reordering), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
> + AV_OPT_FLAG_DECODING_PARAM },
Docs update (doc/demuxers.texi) and libavformat version micro bump is
missing for the new option.
Thanks,
Marton
More information about the ffmpeg-devel
mailing list