Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
@ 2022-01-01 19:26 Marton Balint
  2022-01-01 23:13 ` Pierre-Anthony Lemieux
  0 siblings, 1 reply; 12+ messages in thread
From: Marton Balint @ 2022-01-01 19:26 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Marc-Antoine Arnaud, Marton Balint

From: Marc-Antoine Arnaud <marc-antoine.arnaud@luminvent.com>

Channel reordering is removed from this patch because the new channel layout
API will support it properly.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavformat/mxf.h    |   3 +
 libavformat/mxfdec.c | 286 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 283 insertions(+), 6 deletions(-)

diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index fe9c52732c..d53a16df51 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -50,6 +50,9 @@ enum MXFMetadataSetType {
     TaggedValue,
     TapeDescriptor,
     AVCSubDescriptor,
+    AudioChannelLabelSubDescriptor,
+    SoundfieldGroupLabelSubDescriptor,
+    GroupOfSoundfieldGroupsLabelSubDescriptor,
 };
 
 enum MXFFrameLayout {
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 1d50198279..26b5531720 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -51,11 +51,14 @@
 #include "libavutil/mastering_display_metadata.h"
 #include "libavutil/mathematics.h"
 #include "libavcodec/bytestream.h"
+#include "libavcodec/internal.h"
+#include "libavutil/channel_layout.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/timecode.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
+#include "avlanguage.h"
 #include "internal.h"
 #include "mxf.h"
 
@@ -177,6 +180,8 @@ typedef struct {
     int body_sid;
     MXFWrappingScheme wrapping;
     int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */
+    int require_reordering;
+    int channel_ordering[FF_SANE_NB_CHANNELS];
 } MXFTrack;
 
 typedef struct MXFDescriptor {
@@ -205,6 +210,8 @@ typedef struct MXFDescriptor {
     unsigned int vert_subsampling;
     UID *file_descriptors_refs;
     int file_descriptors_count;
+    UID *sub_descriptors_refs;
+    int sub_descriptors_count;
     int linked_track_id;
     uint8_t *extradata;
     int extradata_size;
@@ -217,6 +224,18 @@ typedef struct MXFDescriptor {
     size_t coll_size;
 } MXFDescriptor;
 
+typedef struct MXFMCASubDescriptor {
+    MXFMetadataSet meta;
+    UID uid;
+    UID mca_link_id;
+    UID soundfield_group_link_id;
+    UID *group_of_soundfield_groups_link_id_refs;
+    int group_of_soundfield_groups_link_id_count;
+    UID mca_label_dictionary_id;
+    int mca_channel_id;
+    char *language;
+} MXFMCASubDescriptor;
+
 typedef struct MXFIndexTableSegment {
     MXFMetadataSet meta;
     int edit_unit_byte_count;
@@ -311,6 +330,7 @@ static const uint8_t mxf_system_item_key_cp[]              = { 0x06,0x0e,0x2b,0x
 static const uint8_t mxf_system_item_key_gc[]              = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
 static const uint8_t mxf_klv_key[]                         = { 0x06,0x0e,0x2b,0x34 };
 static const uint8_t mxf_apple_coll_prefix[]               = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 };
+
 /* complete keys to match */
 static const uint8_t mxf_crypto_source_container_ul[]      = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 };
 static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
@@ -323,6 +343,17 @@ static const uint8_t mxf_indirect_value_utf16be[]          = { 0x42,0x01,0x10,0x
 static const uint8_t mxf_apple_coll_max_cll[]              = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 };
 static const uint8_t mxf_apple_coll_max_fall[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 };
 
+static const uint8_t mxf_mca_label_dictionary_id[]         = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x01,0x00,0x00,0x00 };
+static const uint8_t mxf_mca_tag_symbol[]                  = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x02,0x00,0x00,0x00 };
+static const uint8_t mxf_mca_tag_name[]                    = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x03,0x00,0x00,0x00 };
+static const uint8_t mxf_group_of_soundfield_groups_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x04,0x00,0x00,0x00 };
+static const uint8_t mxf_mca_link_id[]                     = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x05,0x00,0x00,0x00 };
+static const uint8_t mxf_mca_channel_id[]                  = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x04,0x0a,0x00,0x00,0x00,0x00 };
+static const uint8_t mxf_soundfield_group_link_id[]        = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x06,0x00,0x00,0x00 };
+static const uint8_t mxf_mca_rfc5646_spoken_language[]     = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x03,0x01,0x01,0x02,0x03,0x15,0x00,0x00 };
+
+static const uint8_t mxf_sub_descriptor[]                  = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00 };
+
 static const uint8_t mxf_mastering_display_prefix[13]      = { FF_MXF_MasteringDisplay_PREFIX };
 static const uint8_t mxf_mastering_display_uls[4][16] = {
     FF_MXF_MasteringDisplayPrimaries,
@@ -343,6 +374,13 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
         av_freep(&((MXFDescriptor *)*ctx)->mastering);
         av_freep(&((MXFDescriptor *)*ctx)->coll);
         av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs);
+        av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
+        break;
+    case AudioChannelLabelSubDescriptor:
+    case SoundfieldGroupLabelSubDescriptor:
+    case GroupOfSoundfieldGroupsLabelSubDescriptor:
+        av_freep(&((MXFMCASubDescriptor *)*ctx)->language);
+        av_freep(&((MXFMCASubDescriptor *)*ctx)->group_of_soundfield_groups_link_id_refs);
         break;
     case Sequence:
         av_freep(&((MXFSequence *)*ctx)->structural_components_refs);
@@ -906,6 +944,30 @@ static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
     return 0;
 }
 
+static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str)
+{
+    int ret;
+    size_t buf_size;
+
+    if (size < 0 || size > INT_MAX - 1)
+        return AVERROR(EINVAL);
+
+    buf_size = size + 1;
+    av_free(*str);
+    *str = av_malloc(buf_size);
+    if (!*str)
+        return AVERROR(ENOMEM);
+
+    ret = avio_get_str(pb, size, *str, buf_size);
+
+    if (ret < 0) {
+        av_freep(str);
+        return ret;
+    }
+
+    return ret;
+}
+
 static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be)
 {
     int ret;
@@ -1363,11 +1425,40 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
                 descriptor->coll->MaxFALL = avio_rb16(pb);
             }
         }
+
+        if (IS_KLV_KEY(uid, mxf_sub_descriptor))
+            return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count);
+
         break;
     }
     return 0;
 }
 
+static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
+{
+    MXFMCASubDescriptor *mca_sub_descriptor = arg;
+
+    if (IS_KLV_KEY(uid, mxf_mca_label_dictionary_id))
+        avio_read(pb, mca_sub_descriptor->mca_label_dictionary_id, 16);
+
+    if (IS_KLV_KEY(uid, mxf_mca_link_id))
+        avio_read(pb, mca_sub_descriptor->mca_link_id, 16);
+
+    if (IS_KLV_KEY(uid, mxf_soundfield_group_link_id))
+        avio_read(pb, mca_sub_descriptor->soundfield_group_link_id, 16);
+
+    if (IS_KLV_KEY(uid, mxf_group_of_soundfield_groups_link_id))
+        return mxf_read_strong_ref_array(pb, &mca_sub_descriptor->group_of_soundfield_groups_link_id_refs, &mca_sub_descriptor->group_of_soundfield_groups_link_id_count);
+
+    if (IS_KLV_KEY(uid, mxf_mca_channel_id))
+        mca_sub_descriptor->mca_channel_id = avio_rb32(pb);
+
+    if (IS_KLV_KEY(uid, mxf_mca_rfc5646_spoken_language))
+        return mxf_read_us_ascii_string(pb, size, &mca_sub_descriptor->language);
+
+    return 0;
+}
+
 static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size)
 {
     MXFTaggedValue *tagged_value = arg;
@@ -1497,6 +1588,50 @@ static const MXFCodecUL mxf_data_essence_container_uls[] = {
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0, AV_CODEC_ID_NONE },
 };
 
+typedef struct MXFChannelOrderingUL {
+    UID uid;
+    uint64_t layout_mask;
+    enum AVAudioServiceType service_type;
+} MXFChannelOrderingUL;
+
+static const MXFChannelOrderingUL mxf_channel_ordering[] = {
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Left
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT,           AV_AUDIO_SERVICE_TYPE_MAIN }, // Right
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x03,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER,          AV_AUDIO_SERVICE_TYPE_MAIN }, // Center
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x04,0x00,0x00,0x00,0x00 }, AV_CH_LOW_FREQUENCY,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Low Frequency Effects
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x05,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT,             AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x06,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x07,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT,             AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x08,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x09,0x00,0x00,0x00,0x00 }, AV_CH_BACK_LEFT,             AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0a,0x00,0x00,0x00,0x00 }, AV_CH_BACK_RIGHT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0b,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT_OF_CENTER,  AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Center
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0c,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Center
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0d,0x00,0x00,0x00,0x00 }, AV_CH_BACK_CENTER,           AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0e,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER,          AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, // Hearing impaired audio channel
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0f,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER,          AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, // Visually impaired narrative audio channel
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x01,0x00,0x00 }, AV_CH_TOP_FRONT_LEFT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x02,0x00,0x00 }, AV_CH_TOP_FRONT_RIGHT,       AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x03,0x00,0x00 }, AV_CH_TOP_FRONT_CENTER,      AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x04,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x05,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x06,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x07,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x08,0x00,0x00 }, AV_CH_TOP_BACK_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x09,0x00,0x00 }, AV_CH_TOP_BACK_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0a,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Top Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0b,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Top Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0c,0x00,0x00 }, AV_CH_TOP_CENTER,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Top Surround
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0d,0x00,0x00 }, AV_CH_LOW_FREQUENCY,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Front Subwoofer
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0e,0x00,0x00 }, AV_CH_LOW_FREQUENCY_2,       AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Front Subwoofer
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0f,0x00,0x00 }, AV_CH_TOP_BACK_CENTER,       AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear Height
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x10,0x00,0x00 }, AV_CH_BACK_CENTER,           AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x11,0x00,0x00 }, AV_CH_BOTTOM_FRONT_LEFT,     AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Below
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x12,0x00,0x00 }, AV_CH_BOTTOM_FRONT_RIGHT,    AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Below
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x13,0x00,0x00 }, AV_CH_BOTTOM_FRONT_CENTER,   AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Below
+    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,                           AV_AUDIO_SERVICE_TYPE_NB },
+};
+
 static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul)
 {
     int val;
@@ -2295,6 +2430,139 @@ static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *des
     return AVCOL_RANGE_UNSPECIFIED;
 }
 
+static int is_pcm(enum AVCodecID codec_id)
+{
+    /* we only care about "normal" PCM codecs until we get samples */
+    return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
+}
+
+static int set_language(AVFormatContext *s, const char *rfc5646, AVDictionary **met)
+{
+    // language abbr should contain at least 2 chars
+    if (rfc5646 && strlen(rfc5646) > 1) {
+        char primary_tag[4] =
+            {rfc5646[0], rfc5646[1], rfc5646[2] != '-' ? rfc5646[2] : '\0', '\0'};
+
+        const char *iso6392       = ff_convert_lang_to(primary_tag,
+                                                       AV_LANG_ISO639_2_BIBL);
+        if (iso6392)
+            return(av_dict_set(met, "language", iso6392, 0));
+    }
+    return 0;
+}
+
+static MXFMCASubDescriptor *find_mca_link_id(MXFContext *mxf, enum MXFMetadataSetType type, UID *mca_link_id)
+{
+    for (int k = 0; k < mxf->metadata_sets_count; k++) {
+        MXFMCASubDescriptor *group = (MXFMCASubDescriptor*)mxf->metadata_sets[k];
+        if (group->meta.type == type && !memcmp(&group->mca_link_id, mca_link_id, 16))
+            return group;
+    }
+    return NULL;
+}
+
+static int parse_mca_labels(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st)
+{
+    uint64_t routing[FF_SANE_NB_CHANNELS] = {0};
+    char *language = NULL;
+    int ambigous_language = 0;
+    enum AVAudioServiceType service_type = AV_AUDIO_SERVICE_TYPE_NB;
+    int ambigous_service_type = 0;
+    int has_channel_label = 0;
+
+    for (int i = 0; i < descriptor->sub_descriptors_count; i++) {
+        char *channel_language;
+
+        MXFMCASubDescriptor *label = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], AudioChannelLabelSubDescriptor);
+        if (label == NULL)
+            continue;
+
+        has_channel_label = 1;
+        for (const MXFChannelOrderingUL* channel_ordering = mxf_channel_ordering; channel_ordering->uid[0]; channel_ordering++) {
+            if (IS_KLV_KEY(channel_ordering->uid, label->mca_label_dictionary_id)) {
+                int target_channel = label->mca_channel_id;
+                if (target_channel == 0 && descriptor->channels == 1)
+                    target_channel = 1;
+                if (target_channel <= 0 || target_channel > descriptor->channels) {
+                    av_log(mxf->fc, AV_LOG_ERROR, "AudioChannelLabelSubDescriptor has invalid MCA channel ID %d\n", target_channel);
+                    return AVERROR_INVALIDDATA;
+                }
+                routing[target_channel - 1] = channel_ordering->layout_mask;
+                if (service_type == AV_AUDIO_SERVICE_TYPE_NB)
+                    service_type = channel_ordering->service_type;
+                else if (service_type != channel_ordering->service_type)
+                    ambigous_service_type = 1;
+                break;
+            }
+        }
+
+        channel_language = label->language;
+        if (!channel_language) {
+            MXFMCASubDescriptor *group = find_mca_link_id(mxf, SoundfieldGroupLabelSubDescriptor, &label->soundfield_group_link_id);
+            if (group) {
+                channel_language = group->language;
+                if (!channel_language && group->group_of_soundfield_groups_link_id_count) {
+                    MXFMCASubDescriptor *supergroup = find_mca_link_id(mxf, GroupOfSoundfieldGroupsLabelSubDescriptor,
+                                                                       group->group_of_soundfield_groups_link_id_refs);
+                    if (supergroup)
+                        channel_language = supergroup->language;
+                }
+            }
+        }
+        if (channel_language) {
+            if (language && strcmp(language, channel_language))
+                ambigous_language = 1;
+            else
+                language = channel_language;
+        }
+    }
+
+    if (language && !ambigous_language) {
+       int ret = set_language(mxf->fc, language, &st->metadata);
+       if (ret < 0)
+           return ret;
+    }
+
+    if (service_type != AV_AUDIO_SERVICE_TYPE_NB && service_type != AV_AUDIO_SERVICE_TYPE_MAIN && !ambigous_service_type) {
+        enum AVAudioServiceType *ast;
+        uint8_t* side_data = av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE, sizeof(*ast));
+        if (!side_data)
+            return AVERROR(ENOMEM);
+        ast = (enum AVAudioServiceType*)side_data;
+        *ast = service_type;
+    }
+
+    if (has_channel_label) {
+        uint64_t channel_layout = 0;
+
+        for (int i = 0; i < descriptor->channels; i++) {
+            if (!routing[i]) {
+                av_log(mxf->fc, AV_LOG_WARNING, "Designation of audio channel %d in stream #%d is unknown or unsupported, "
+                                                "falling back to unknown channel layout\n", st->index, i);
+                return 0;
+            }
+            if (channel_layout & routing[i]) {
+                av_log(mxf->fc, AV_LOG_WARNING, "%s audio channel is used multiple times in stream #%d, "
+                                                "falling back to unknown channel layout\n",
+                                                av_get_channel_name(routing[i]), st->index);
+                return 0;
+            }
+            if (routing[i] < channel_layout) {
+                av_log(mxf->fc, AV_LOG_WARNING, "stream #%d is not in in native channel order, "
+                                                "falling back to unknown channel layout\n", st->index);
+                return 0;
+            }
+            channel_layout |= routing[i];
+        }
+
+        av_assert0(descriptor->channels == av_get_channel_layout_nb_channels(channel_layout));
+
+        st->codecpar->channel_layout = channel_layout;
+    }
+
+    return 0;
+}
+
 static int mxf_parse_structural_metadata(MXFContext *mxf)
 {
     MXFPackage *material_package = NULL;
@@ -2691,6 +2959,15 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
                 sti->need_parsing = AVSTREAM_PARSE_FULL;
             }
             st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
+
+            if (descriptor->channels <= 0 || descriptor->channels >= FF_SANE_NB_CHANNELS) {
+                av_log(mxf->fc, AV_LOG_ERROR, "Invalid number of channels %d, must be less than %d\n", descriptor->channels, FF_SANE_NB_CHANNELS);
+                return AVERROR_INVALIDDATA;
+            }
+
+            ret = parse_mca_labels(mxf, source_track, descriptor, st);
+            if (ret < 0)
+                return ret;
         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
             enum AVMediaType type;
             container_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
@@ -2891,6 +3168,9 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* VANC/VBI - SMPTE 436M */
     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2AudioDescriptor */
     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x64,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* DC Timed Text Descriptor */
+    { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6b,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), AudioChannelLabelSubDescriptor },
+    { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6c,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), SoundfieldGroupLabelSubDescriptor },
+    { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6d,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor },
     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
@@ -3190,12 +3470,6 @@ static void mxf_compute_essence_containers(AVFormatContext *s)
     }
 }
 
-static int is_pcm(enum AVCodecID codec_id)
-{
-    /* we only care about "normal" PCM codecs until we get samples */
-    return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
-}
-
 static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
 {
     int i;
-- 
2.31.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-01 19:26 [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information Marton Balint
@ 2022-01-01 23:13 ` Pierre-Anthony Lemieux
  2022-01-02  1:11   ` Marton Balint
  2022-01-02  1:35   ` Andreas Rheinhardt
  0 siblings, 2 replies; 12+ messages in thread
From: Pierre-Anthony Lemieux @ 2022-01-01 23:13 UTC (permalink / raw)
  To: FFmpeg development discussions and patches
  Cc: Marc-Antoine Arnaud, Marton Balint

Minor suggestion below.

In addition, will sample file(s) be added to FATE? Below are two examples:

http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf

On Sat, Jan 1, 2022 at 11:27 AM Marton Balint <cus@passwd.hu> wrote:
>
> From: Marc-Antoine Arnaud <marc-antoine.arnaud@luminvent.com>
>
> Channel reordering is removed from this patch because the new channel layout
> API will support it properly.
>
> Signed-off-by: Marton Balint <cus@passwd.hu>
> ---
>  libavformat/mxf.h    |   3 +
>  libavformat/mxfdec.c | 286 ++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 283 insertions(+), 6 deletions(-)
>
> diff --git a/libavformat/mxf.h b/libavformat/mxf.h
> index fe9c52732c..d53a16df51 100644
> --- a/libavformat/mxf.h
> +++ b/libavformat/mxf.h
> @@ -50,6 +50,9 @@ enum MXFMetadataSetType {
>      TaggedValue,
>      TapeDescriptor,
>      AVCSubDescriptor,
> +    AudioChannelLabelSubDescriptor,
> +    SoundfieldGroupLabelSubDescriptor,
> +    GroupOfSoundfieldGroupsLabelSubDescriptor,
>  };
>
>  enum MXFFrameLayout {
> diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
> index 1d50198279..26b5531720 100644
> --- a/libavformat/mxfdec.c
> +++ b/libavformat/mxfdec.c
> @@ -51,11 +51,14 @@
>  #include "libavutil/mastering_display_metadata.h"
>  #include "libavutil/mathematics.h"
>  #include "libavcodec/bytestream.h"
> +#include "libavcodec/internal.h"
> +#include "libavutil/channel_layout.h"
>  #include "libavutil/intreadwrite.h"
>  #include "libavutil/parseutils.h"
>  #include "libavutil/timecode.h"
>  #include "libavutil/opt.h"
>  #include "avformat.h"
> +#include "avlanguage.h"
>  #include "internal.h"
>  #include "mxf.h"
>
> @@ -177,6 +180,8 @@ typedef struct {
>      int body_sid;
>      MXFWrappingScheme wrapping;
>      int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */
> +    int require_reordering;
> +    int channel_ordering[FF_SANE_NB_CHANNELS];
>  } MXFTrack;
>
>  typedef struct MXFDescriptor {
> @@ -205,6 +210,8 @@ typedef struct MXFDescriptor {
>      unsigned int vert_subsampling;
>      UID *file_descriptors_refs;
>      int file_descriptors_count;
> +    UID *sub_descriptors_refs;
> +    int sub_descriptors_count;
>      int linked_track_id;
>      uint8_t *extradata;
>      int extradata_size;
> @@ -217,6 +224,18 @@ typedef struct MXFDescriptor {
>      size_t coll_size;
>  } MXFDescriptor;
>
> +typedef struct MXFMCASubDescriptor {
> +    MXFMetadataSet meta;
> +    UID uid;
> +    UID mca_link_id;
> +    UID soundfield_group_link_id;
> +    UID *group_of_soundfield_groups_link_id_refs;
> +    int group_of_soundfield_groups_link_id_count;
> +    UID mca_label_dictionary_id;
> +    int mca_channel_id;
> +    char *language;
> +} MXFMCASubDescriptor;
> +
>  typedef struct MXFIndexTableSegment {
>      MXFMetadataSet meta;
>      int edit_unit_byte_count;
> @@ -311,6 +330,7 @@ static const uint8_t mxf_system_item_key_cp[]              = { 0x06,0x0e,0x2b,0x
>  static const uint8_t mxf_system_item_key_gc[]              = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
>  static const uint8_t mxf_klv_key[]                         = { 0x06,0x0e,0x2b,0x34 };
>  static const uint8_t mxf_apple_coll_prefix[]               = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 };
> +
>  /* complete keys to match */
>  static const uint8_t mxf_crypto_source_container_ul[]      = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 };
>  static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
> @@ -323,6 +343,17 @@ static const uint8_t mxf_indirect_value_utf16be[]          = { 0x42,0x01,0x10,0x
>  static const uint8_t mxf_apple_coll_max_cll[]              = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 };
>  static const uint8_t mxf_apple_coll_max_fall[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 };
>
> +static const uint8_t mxf_mca_label_dictionary_id[]         = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x01,0x00,0x00,0x00 };
> +static const uint8_t mxf_mca_tag_symbol[]                  = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x02,0x00,0x00,0x00 };
> +static const uint8_t mxf_mca_tag_name[]                    = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x03,0x00,0x00,0x00 };
> +static const uint8_t mxf_group_of_soundfield_groups_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x04,0x00,0x00,0x00 };
> +static const uint8_t mxf_mca_link_id[]                     = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x05,0x00,0x00,0x00 };
> +static const uint8_t mxf_mca_channel_id[]                  = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x04,0x0a,0x00,0x00,0x00,0x00 };
> +static const uint8_t mxf_soundfield_group_link_id[]        = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x06,0x00,0x00,0x00 };
> +static const uint8_t mxf_mca_rfc5646_spoken_language[]     = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x03,0x01,0x01,0x02,0x03,0x15,0x00,0x00 };
> +
> +static const uint8_t mxf_sub_descriptor[]                  = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00 };
> +
>  static const uint8_t mxf_mastering_display_prefix[13]      = { FF_MXF_MasteringDisplay_PREFIX };
>  static const uint8_t mxf_mastering_display_uls[4][16] = {
>      FF_MXF_MasteringDisplayPrimaries,
> @@ -343,6 +374,13 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
>          av_freep(&((MXFDescriptor *)*ctx)->mastering);
>          av_freep(&((MXFDescriptor *)*ctx)->coll);
>          av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs);
> +        av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
> +        break;
> +    case AudioChannelLabelSubDescriptor:
> +    case SoundfieldGroupLabelSubDescriptor:
> +    case GroupOfSoundfieldGroupsLabelSubDescriptor:
> +        av_freep(&((MXFMCASubDescriptor *)*ctx)->language);
> +        av_freep(&((MXFMCASubDescriptor *)*ctx)->group_of_soundfield_groups_link_id_refs);
>          break;
>      case Sequence:
>          av_freep(&((MXFSequence *)*ctx)->structural_components_refs);
> @@ -906,6 +944,30 @@ static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
>      return 0;
>  }
>
> +static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str)
> +{
> +    int ret;
> +    size_t buf_size;
> +
> +    if (size < 0 || size > INT_MAX - 1)
> +        return AVERROR(EINVAL);
> +
> +    buf_size = size + 1;
> +    av_free(*str);
> +    *str = av_malloc(buf_size);
> +    if (!*str)
> +        return AVERROR(ENOMEM);
> +
> +    ret = avio_get_str(pb, size, *str, buf_size);
> +
> +    if (ret < 0) {
> +        av_freep(str);
> +        return ret;
> +    }
> +
> +    return ret;
> +}
> +
>  static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be)
>  {
>      int ret;
> @@ -1363,11 +1425,40 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
>                  descriptor->coll->MaxFALL = avio_rb16(pb);
>              }
>          }
> +
> +        if (IS_KLV_KEY(uid, mxf_sub_descriptor))
> +            return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count);
> +
>          break;
>      }
>      return 0;
>  }
>
> +static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
> +{
> +    MXFMCASubDescriptor *mca_sub_descriptor = arg;
> +
> +    if (IS_KLV_KEY(uid, mxf_mca_label_dictionary_id))
> +        avio_read(pb, mca_sub_descriptor->mca_label_dictionary_id, 16);
> +
> +    if (IS_KLV_KEY(uid, mxf_mca_link_id))
> +        avio_read(pb, mca_sub_descriptor->mca_link_id, 16);
> +
> +    if (IS_KLV_KEY(uid, mxf_soundfield_group_link_id))
> +        avio_read(pb, mca_sub_descriptor->soundfield_group_link_id, 16);
> +
> +    if (IS_KLV_KEY(uid, mxf_group_of_soundfield_groups_link_id))
> +        return mxf_read_strong_ref_array(pb, &mca_sub_descriptor->group_of_soundfield_groups_link_id_refs, &mca_sub_descriptor->group_of_soundfield_groups_link_id_count);
> +
> +    if (IS_KLV_KEY(uid, mxf_mca_channel_id))
> +        mca_sub_descriptor->mca_channel_id = avio_rb32(pb);
> +
> +    if (IS_KLV_KEY(uid, mxf_mca_rfc5646_spoken_language))
> +        return mxf_read_us_ascii_string(pb, size, &mca_sub_descriptor->language);
> +
> +    return 0;
> +}
> +
>  static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size)
>  {
>      MXFTaggedValue *tagged_value = arg;
> @@ -1497,6 +1588,50 @@ static const MXFCodecUL mxf_data_essence_container_uls[] = {
>      { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0, AV_CODEC_ID_NONE },
>  };
>
> +typedef struct MXFChannelOrderingUL {
> +    UID uid;
> +    uint64_t layout_mask;
> +    enum AVAudioServiceType service_type;
> +} MXFChannelOrderingUL;
> +
> +static const MXFChannelOrderingUL mxf_channel_ordering[] = {
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Left
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT,           AV_AUDIO_SERVICE_TYPE_MAIN }, // Right
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x03,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER,          AV_AUDIO_SERVICE_TYPE_MAIN }, // Center
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x04,0x00,0x00,0x00,0x00 }, AV_CH_LOW_FREQUENCY,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Low Frequency Effects
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x05,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT,             AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x06,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x07,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT,             AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x08,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x09,0x00,0x00,0x00,0x00 }, AV_CH_BACK_LEFT,             AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0a,0x00,0x00,0x00,0x00 }, AV_CH_BACK_RIGHT,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0b,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT_OF_CENTER,  AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Center
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0c,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Center
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0d,0x00,0x00,0x00,0x00 }, AV_CH_BACK_CENTER,           AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0e,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER,          AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, // Hearing impaired audio channel
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0f,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER,          AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, // Visually impaired narrative audio channel
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x01,0x00,0x00 }, AV_CH_TOP_FRONT_LEFT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x02,0x00,0x00 }, AV_CH_TOP_FRONT_RIGHT,       AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x03,0x00,0x00 }, AV_CH_TOP_FRONT_CENTER,      AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x04,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x05,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x06,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x07,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x08,0x00,0x00 }, AV_CH_TOP_BACK_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x09,0x00,0x00 }, AV_CH_TOP_BACK_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0a,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Top Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0b,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT,        AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Top Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0c,0x00,0x00 }, AV_CH_TOP_CENTER,            AV_AUDIO_SERVICE_TYPE_MAIN }, // Top Surround
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0d,0x00,0x00 }, AV_CH_LOW_FREQUENCY,         AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Front Subwoofer
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0e,0x00,0x00 }, AV_CH_LOW_FREQUENCY_2,       AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Front Subwoofer
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0f,0x00,0x00 }, AV_CH_TOP_BACK_CENTER,       AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear Height
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x10,0x00,0x00 }, AV_CH_BACK_CENTER,           AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x11,0x00,0x00 }, AV_CH_BOTTOM_FRONT_LEFT,     AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Below
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x12,0x00,0x00 }, AV_CH_BOTTOM_FRONT_RIGHT,    AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Below
> +    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x13,0x00,0x00 }, AV_CH_BOTTOM_FRONT_CENTER,   AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Below
> +    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,                           AV_AUDIO_SERVICE_TYPE_NB },
> +};

I suggest adding the following audio channels, which are specified in
SMPTE ST 2067-8 [1] and have a direct mapping to ffmpeg audio
channels:

urn:smpte:ul:060e2b34.0401010d.03020120.03000000 (Left Total) ->
AV_CH_STEREO_LEFT
urn:smpte:ul:060e2b34.0401010d.03020120.04000000 (RightTotal) ->
AV_CH_STEREO_RIGHT

[1] https://registry.smpte-ra.org/view/published/labels_view.html

> +
>  static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul)
>  {
>      int val;
> @@ -2295,6 +2430,139 @@ static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *des
>      return AVCOL_RANGE_UNSPECIFIED;
>  }
>
> +static int is_pcm(enum AVCodecID codec_id)
> +{
> +    /* we only care about "normal" PCM codecs until we get samples */
> +    return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
> +}
> +
> +static int set_language(AVFormatContext *s, const char *rfc5646, AVDictionary **met)
> +{
> +    // language abbr should contain at least 2 chars
> +    if (rfc5646 && strlen(rfc5646) > 1) {
> +        char primary_tag[4] =
> +            {rfc5646[0], rfc5646[1], rfc5646[2] != '-' ? rfc5646[2] : '\0', '\0'};
> +
> +        const char *iso6392       = ff_convert_lang_to(primary_tag,
> +                                                       AV_LANG_ISO639_2_BIBL);
> +        if (iso6392)
> +            return(av_dict_set(met, "language", iso6392, 0));
> +    }
> +    return 0;
> +}
> +
> +static MXFMCASubDescriptor *find_mca_link_id(MXFContext *mxf, enum MXFMetadataSetType type, UID *mca_link_id)
> +{
> +    for (int k = 0; k < mxf->metadata_sets_count; k++) {
> +        MXFMCASubDescriptor *group = (MXFMCASubDescriptor*)mxf->metadata_sets[k];
> +        if (group->meta.type == type && !memcmp(&group->mca_link_id, mca_link_id, 16))
> +            return group;
> +    }
> +    return NULL;
> +}
> +
> +static int parse_mca_labels(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st)
> +{
> +    uint64_t routing[FF_SANE_NB_CHANNELS] = {0};
> +    char *language = NULL;
> +    int ambigous_language = 0;
> +    enum AVAudioServiceType service_type = AV_AUDIO_SERVICE_TYPE_NB;
> +    int ambigous_service_type = 0;
> +    int has_channel_label = 0;
> +
> +    for (int i = 0; i < descriptor->sub_descriptors_count; i++) {
> +        char *channel_language;
> +
> +        MXFMCASubDescriptor *label = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], AudioChannelLabelSubDescriptor);
> +        if (label == NULL)
> +            continue;
> +
> +        has_channel_label = 1;
> +        for (const MXFChannelOrderingUL* channel_ordering = mxf_channel_ordering; channel_ordering->uid[0]; channel_ordering++) {
> +            if (IS_KLV_KEY(channel_ordering->uid, label->mca_label_dictionary_id)) {
> +                int target_channel = label->mca_channel_id;
> +                if (target_channel == 0 && descriptor->channels == 1)
> +                    target_channel = 1;
> +                if (target_channel <= 0 || target_channel > descriptor->channels) {
> +                    av_log(mxf->fc, AV_LOG_ERROR, "AudioChannelLabelSubDescriptor has invalid MCA channel ID %d\n", target_channel);
> +                    return AVERROR_INVALIDDATA;
> +                }
> +                routing[target_channel - 1] = channel_ordering->layout_mask;
> +                if (service_type == AV_AUDIO_SERVICE_TYPE_NB)
> +                    service_type = channel_ordering->service_type;
> +                else if (service_type != channel_ordering->service_type)
> +                    ambigous_service_type = 1;
> +                break;
> +            }
> +        }
> +
> +        channel_language = label->language;
> +        if (!channel_language) {
> +            MXFMCASubDescriptor *group = find_mca_link_id(mxf, SoundfieldGroupLabelSubDescriptor, &label->soundfield_group_link_id);
> +            if (group) {
> +                channel_language = group->language;
> +                if (!channel_language && group->group_of_soundfield_groups_link_id_count) {
> +                    MXFMCASubDescriptor *supergroup = find_mca_link_id(mxf, GroupOfSoundfieldGroupsLabelSubDescriptor,
> +                                                                       group->group_of_soundfield_groups_link_id_refs);
> +                    if (supergroup)
> +                        channel_language = supergroup->language;
> +                }
> +            }
> +        }
> +        if (channel_language) {
> +            if (language && strcmp(language, channel_language))
> +                ambigous_language = 1;
> +            else
> +                language = channel_language;
> +        }
> +    }
> +
> +    if (language && !ambigous_language) {
> +       int ret = set_language(mxf->fc, language, &st->metadata);
> +       if (ret < 0)
> +           return ret;
> +    }
> +
> +    if (service_type != AV_AUDIO_SERVICE_TYPE_NB && service_type != AV_AUDIO_SERVICE_TYPE_MAIN && !ambigous_service_type) {
> +        enum AVAudioServiceType *ast;
> +        uint8_t* side_data = av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE, sizeof(*ast));
> +        if (!side_data)
> +            return AVERROR(ENOMEM);
> +        ast = (enum AVAudioServiceType*)side_data;
> +        *ast = service_type;
> +    }
> +
> +    if (has_channel_label) {
> +        uint64_t channel_layout = 0;
> +
> +        for (int i = 0; i < descriptor->channels; i++) {
> +            if (!routing[i]) {
> +                av_log(mxf->fc, AV_LOG_WARNING, "Designation of audio channel %d in stream #%d is unknown or unsupported, "
> +                                                "falling back to unknown channel layout\n", st->index, i);
> +                return 0;
> +            }
> +            if (channel_layout & routing[i]) {
> +                av_log(mxf->fc, AV_LOG_WARNING, "%s audio channel is used multiple times in stream #%d, "
> +                                                "falling back to unknown channel layout\n",
> +                                                av_get_channel_name(routing[i]), st->index);
> +                return 0;
> +            }
> +            if (routing[i] < channel_layout) {
> +                av_log(mxf->fc, AV_LOG_WARNING, "stream #%d is not in in native channel order, "
> +                                                "falling back to unknown channel layout\n", st->index);
> +                return 0;
> +            }
> +            channel_layout |= routing[i];
> +        }
> +
> +        av_assert0(descriptor->channels == av_get_channel_layout_nb_channels(channel_layout));
> +
> +        st->codecpar->channel_layout = channel_layout;
> +    }
> +
> +    return 0;
> +}
> +
>  static int mxf_parse_structural_metadata(MXFContext *mxf)
>  {
>      MXFPackage *material_package = NULL;
> @@ -2691,6 +2959,15 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
>                  sti->need_parsing = AVSTREAM_PARSE_FULL;
>              }
>              st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
> +
> +            if (descriptor->channels <= 0 || descriptor->channels >= FF_SANE_NB_CHANNELS) {
> +                av_log(mxf->fc, AV_LOG_ERROR, "Invalid number of channels %d, must be less than %d\n", descriptor->channels, FF_SANE_NB_CHANNELS);
> +                return AVERROR_INVALIDDATA;
> +            }
> +
> +            ret = parse_mca_labels(mxf, source_track, descriptor, st);
> +            if (ret < 0)
> +                return ret;
>          } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
>              enum AVMediaType type;
>              container_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
> @@ -2891,6 +3168,9 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
>      { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* VANC/VBI - SMPTE 436M */
>      { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2AudioDescriptor */
>      { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x64,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* DC Timed Text Descriptor */
> +    { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6b,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), AudioChannelLabelSubDescriptor },
> +    { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6c,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), SoundfieldGroupLabelSubDescriptor },
> +    { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6d,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor },
>      { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
>      { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
>      { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
> @@ -3190,12 +3470,6 @@ static void mxf_compute_essence_containers(AVFormatContext *s)
>      }
>  }
>
> -static int is_pcm(enum AVCodecID codec_id)
> -{
> -    /* we only care about "normal" PCM codecs until we get samples */
> -    return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
> -}
> -
>  static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
>  {
>      int i;
> --
> 2.31.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-01 23:13 ` Pierre-Anthony Lemieux
@ 2022-01-02  1:11   ` Marton Balint
  2022-01-02  2:16     ` Pierre-Anthony Lemieux
  2022-01-02 17:35     ` Michael Niedermayer
  2022-01-02  1:35   ` Andreas Rheinhardt
  1 sibling, 2 replies; 12+ messages in thread
From: Marton Balint @ 2022-01-02  1:11 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:

> Minor suggestion below.
>
> In addition, will sample file(s) be added to FATE? Below are two examples:
>
> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf

Good idea, can someone with access please upload these to the fate mxf 
folder?

[...]

> I suggest adding the following audio channels, which are specified in
> SMPTE ST 2067-8 [1] and have a direct mapping to ffmpeg audio
> channels:
>
> urn:smpte:ul:060e2b34.0401010d.03020120.03000000 (Left Total) ->
> AV_CH_STEREO_LEFT
> urn:smpte:ul:060e2b34.0401010d.03020120.04000000 (RightTotal) ->
> AV_CH_STEREO_RIGHT
>
> [1] https://registry.smpte-ra.org/view/published/labels_view.html

Unfortunately this is a Dolby encoded stereo mix, not an ordinary LeftOnly 
/ RightOnly mix. So I am not how this should be signalled.

Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-01 23:13 ` Pierre-Anthony Lemieux
  2022-01-02  1:11   ` Marton Balint
@ 2022-01-02  1:35   ` Andreas Rheinhardt
  2022-01-02  1:54     ` Pierre-Anthony Lemieux
  1 sibling, 1 reply; 12+ messages in thread
From: Andreas Rheinhardt @ 2022-01-02  1:35 UTC (permalink / raw)
  To: ffmpeg-devel

Pierre-Anthony Lemieux:
> Minor suggestion below.
> 
> In addition, will sample file(s) be added to FATE? Below are two examples:
> 
> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
> 

These files are 1.62MiB each, having 49 packets of lossless audio. Would
it decrease coverage if this were reduced? After all, the amount of
audio should not matter for channel reorderings.

- Andreas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02  1:35   ` Andreas Rheinhardt
@ 2022-01-02  1:54     ` Pierre-Anthony Lemieux
  2022-01-02 10:33       ` Marton Balint
  2022-01-03  7:12       ` Andreas Rheinhardt
  0 siblings, 2 replies; 12+ messages in thread
From: Pierre-Anthony Lemieux @ 2022-01-02  1:54 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sat, Jan 1, 2022 at 5:35 PM Andreas Rheinhardt
<andreas.rheinhardt@outlook.com> wrote:
>
> Pierre-Anthony Lemieux:
> > Minor suggestion below.
> >
> > In addition, will sample file(s) be added to FATE? Below are two examples:
> >
> > http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
> > http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
> >
>
> These files are 1.62MiB each, having 49 packets of lossless audio. Would
> it decrease coverage if this were reduced? After all, the amount of
> audio should not matter for channel reorderings.

Each channel contains a synthesized human voice that announces the
name of the channel, so that a reviewer can, by simple inspection,
confirm the expected channel order. This will be particularly useful
when automatic channel reordering is performed.

The contents of each channel could be changed to a single tone with
each channel assigned a different tone, e.g. 1 to 6 kHz. This might
make the files shorter.

>
> - Andreas
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02  1:11   ` Marton Balint
@ 2022-01-02  2:16     ` Pierre-Anthony Lemieux
  2022-01-02 10:26       ` Marton Balint
  2022-01-02 17:35     ` Michael Niedermayer
  1 sibling, 1 reply; 12+ messages in thread
From: Pierre-Anthony Lemieux @ 2022-01-02  2:16 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sat, Jan 1, 2022 at 5:11 PM Marton Balint <cus@passwd.hu> wrote:
>
>
>
> On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:
>
> > Minor suggestion below.
> >
> > In addition, will sample file(s) be added to FATE? Below are two examples:
> >
> > http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
> > http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
>
> Good idea, can someone with access please upload these to the fate mxf
> folder?
>
> [...]
>
> > I suggest adding the following audio channels, which are specified in
> > SMPTE ST 2067-8 [1] and have a direct mapping to ffmpeg audio
> > channels:AV_CH_STEREO_LEFT
> >
> > urn:smpte:ul:060e2b34.0401010d.03020120.03000000 (Left Total) ->
> > AV_CH_STEREO_LEFT
> > urn:smpte:ul:060e2b34.0401010d.03020120.04000000 (RightTotal) ->
> > AV_CH_STEREO_RIGHT
> >
> > [1] https://registry.smpte-ra.org/view/published/labels_view.html
>
> Unfortunately this is a Dolby encoded stereo mix, not an ordinary LeftOnly
> / RightOnly mix. So I am not how this should be signalled.

My interpretation below.

In "mov_chan.c", AV_CH_LAYOUT_STEREO_DOWNMIX means
MOV_CH_LAYOUT_MATRIXSTEREO [1], which is defined in Core Audio [2].

LtRt, i.e. matrix-encoded audio, is not generally Dolby-specific [3].

[1] https://github.com/FFmpeg/FFmpeg/blob/d6b2357eddca392ee137cb2a92ff178a0a7d0cce/libavformat/mov_chan.c#L168
[2] https://developer.apple.com/documentation/coreaudiotypes/1572101-audio_channel_layout_tags/kaudiochannellayouttag_matrixstereo?changes=_8_7&language=objc
[3] https://en.wikipedia.org/wiki/Matrix_decoder

>
> Regards,
> Marton
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02  2:16     ` Pierre-Anthony Lemieux
@ 2022-01-02 10:26       ` Marton Balint
  2022-01-08 18:48         ` Marton Balint
  0 siblings, 1 reply; 12+ messages in thread
From: Marton Balint @ 2022-01-02 10:26 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:

> On Sat, Jan 1, 2022 at 5:11 PM Marton Balint <cus@passwd.hu> wrote:
>>
>>
>>
>> On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:
>>
>>> Minor suggestion below.
>>>
>>> In addition, will sample file(s) be added to FATE? Below are two examples:
>>>
>>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
>>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
>>
>> Good idea, can someone with access please upload these to the fate mxf
>> folder?
>>
>> [...]
>>
>>> I suggest adding the following audio channels, which are specified in
>>> SMPTE ST 2067-8 [1] and have a direct mapping to ffmpeg audio
>>> channels:AV_CH_STEREO_LEFT
>>>
>>> urn:smpte:ul:060e2b34.0401010d.03020120.03000000 (Left Total) ->
>>> AV_CH_STEREO_LEFT
>>> urn:smpte:ul:060e2b34.0401010d.03020120.04000000 (RightTotal) ->
>>> AV_CH_STEREO_RIGHT
>>>
>>> [1] https://registry.smpte-ra.org/view/published/labels_view.html
>>
>> Unfortunately this is a Dolby encoded stereo mix, not an ordinary LeftOnly
>> / RightOnly mix. So I am not how this should be signalled.
>
> My interpretation below.
>
> In "mov_chan.c", AV_CH_LAYOUT_STEREO_DOWNMIX means
> MOV_CH_LAYOUT_MATRIXSTEREO [1], which is defined in Core Audio [2].
>
> LtRt, i.e. matrix-encoded audio, is not generally Dolby-specific [3].
>
> [1] https://github.com/FFmpeg/FFmpeg/blob/d6b2357eddca392ee137cb2a92ff178a0a7d0cce/libavformat/mov_chan.c#L168
> [2] https://developer.apple.com/documentation/coreaudiotypes/1572101-audio_channel_layout_tags/kaudiochannellayouttag_matrixstereo?changes=_8_7&language=objc
> [3] https://en.wikipedia.org/wiki/Matrix_decoder

Well, ok, I will add these two labels then before pushing.

Thanks,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02  1:54     ` Pierre-Anthony Lemieux
@ 2022-01-02 10:33       ` Marton Balint
  2022-01-03  7:12       ` Andreas Rheinhardt
  1 sibling, 0 replies; 12+ messages in thread
From: Marton Balint @ 2022-01-02 10:33 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:

> On Sat, Jan 1, 2022 at 5:35 PM Andreas Rheinhardt
> <andreas.rheinhardt@outlook.com> wrote:
>>
>> Pierre-Anthony Lemieux:
>>> Minor suggestion below.
>>>
>>> In addition, will sample file(s) be added to FATE? Below are two examples:
>>>
>>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
>>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
>>>
>>
>> These files are 1.62MiB each, having 49 packets of lossless audio. Would
>> it decrease coverage if this were reduced? After all, the amount of
>> audio should not matter for channel reorderings.
>
> Each channel contains a synthesized human voice that announces the
> name of the channel, so that a reviewer can, by simple inspection,
> confirm the expected channel order. This will be particularly useful
> when automatic channel reordering is performed.
>
> The contents of each channel could be changed to a single tone with
> each channel assigned a different tone, e.g. 1 to 6 kHz. This might
> make the files shorter.

I'd rather stick to the human voice.

Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02  1:11   ` Marton Balint
  2022-01-02  2:16     ` Pierre-Anthony Lemieux
@ 2022-01-02 17:35     ` Michael Niedermayer
  1 sibling, 0 replies; 12+ messages in thread
From: Michael Niedermayer @ 2022-01-02 17:35 UTC (permalink / raw)
  To: FFmpeg development discussions and patches


[-- Attachment #1.1: Type: text/plain, Size: 899 bytes --]

On Sun, Jan 02, 2022 at 02:11:01AM +0100, Marton Balint wrote:
> 
> 
> On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:
> 
> > Minor suggestion below.
> > 
> > In addition, will sample file(s) be added to FATE? Below are two examples:
> > 
> > http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
> > http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
> 
> Good idea, can someone with access please upload these to the fate mxf
> folder?

you should CC samples-request once theres agreement what to upload

thx

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Many that live deserve death. And some that die deserve life. Can you give
it to them? Then do not be too eager to deal out death in judgement. For
even the very wise cannot see all ends. -- Gandalf

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02  1:54     ` Pierre-Anthony Lemieux
  2022-01-02 10:33       ` Marton Balint
@ 2022-01-03  7:12       ` Andreas Rheinhardt
  2022-01-04  4:38         ` Pierre-Anthony Lemieux
  1 sibling, 1 reply; 12+ messages in thread
From: Andreas Rheinhardt @ 2022-01-03  7:12 UTC (permalink / raw)
  To: ffmpeg-devel

Pierre-Anthony Lemieux:
> On Sat, Jan 1, 2022 at 5:35 PM Andreas Rheinhardt
> <andreas.rheinhardt@outlook.com> wrote:
>>
>> Pierre-Anthony Lemieux:
>>> Minor suggestion below.
>>>
>>> In addition, will sample file(s) be added to FATE? Below are two examples:
>>>
>>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
>>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
>>>
>>
>> These files are 1.62MiB each, having 49 packets of lossless audio. Would
>> it decrease coverage if this were reduced? After all, the amount of
>> audio should not matter for channel reorderings.
> 
> Each channel contains a synthesized human voice that announces the
> name of the channel, so that a reviewer can, by simple inspection,
> confirm the expected channel order. This will be particularly useful
> when automatic channel reordering is performed.
> 
> The contents of each channel could be changed to a single tone with
> each channel assigned a different tone, e.g. 1 to 6 kHz. This might
> make the files shorter.
> 

A human voice sounds like something that is nice to have; but does it
have to be 24bit? As I see it, mxf allows 16bit sound everywhere where
it allows 24bit. Furthermore, the channels will still be recognizably
different if the audio is cut off at 1s (this will cut off the "effect"
from "low frequency effect" and will also cut off beeps for the others).

- Andreas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-03  7:12       ` Andreas Rheinhardt
@ 2022-01-04  4:38         ` Pierre-Anthony Lemieux
  0 siblings, 0 replies; 12+ messages in thread
From: Pierre-Anthony Lemieux @ 2022-01-04  4:38 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sun, Jan 2, 2022 at 11:13 PM Andreas Rheinhardt
<andreas.rheinhardt@outlook.com> wrote:
>
> Pierre-Anthony Lemieux:
> > On Sat, Jan 1, 2022 at 5:35 PM Andreas Rheinhardt
> > <andreas.rheinhardt@outlook.com> wrote:
> >>
> >> Pierre-Anthony Lemieux:
> >>> Minor suggestion below.
> >>>
> >>> In addition, will sample file(s) be added to FATE? Below are two examples:
> >>>
> >>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
> >>> http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
> >>>
> >>
> >> These files are 1.62MiB each, having 49 packets of lossless audio. Would
> >> it decrease coverage if this were reduced? After all, the amount of
> >> audio should not matter for channel reorderings.
> >
> > Each channel contains a synthesized human voice that announces the
> > name of the channel, so that a reviewer can, by simple inspection,
> > confirm the expected channel order. This will be particularly useful
> > when automatic channel reordering is performed.
> >
> > The contents of each channel could be changed to a single tone with
> > each channel assigned a different tone, e.g. 1 to 6 kHz. This might
> > make the files shorter.
> >
>
> A human voice sounds like something that is nice to have; but does it
> have to be 24bit? As I see it, mxf allows 16bit sound everywhere where
> it allows 24bit.

I have never seen or created an MXF file that uses MCA and that has
16-bit PCM. I do not recommend treading new ground.

> Furthermore, the channels will still be recognizably
> different if the audio is cut off at 1s (this will cut off the "effect"
> from "low frequency effect" and will also cut off beeps for the others).

Ok. See:

http://ffmpeg-imf-samples-public.s3-website-us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.v2.mxf
http://ffmpeg-imf-samples-public.s3-website-us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.v2.mxf

>
> - Andreas
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information
  2022-01-02 10:26       ` Marton Balint
@ 2022-01-08 18:48         ` Marton Balint
  0 siblings, 0 replies; 12+ messages in thread
From: Marton Balint @ 2022-01-08 18:48 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On Sun, 2 Jan 2022, Marton Balint wrote:

>
>
> On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:
>
>>  On Sat, Jan 1, 2022 at 5:11 PM Marton Balint <cus@passwd.hu> wrote:
>>> 
>>> 
>>>
>>>  On Sat, 1 Jan 2022, Pierre-Anthony Lemieux wrote:
>>>
>>>>  Minor suggestion below.
>>>>
>>>>  In addition, will sample file(s) be added to FATE? Below are two
>>>>  examples:
>>>>
>>>>  http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_r_c_lfe_ls_rs.mxf
>>>>  http://ffmpeg-imf-samples-public.s3.us-west-1.amazonaws.com/callout_51_l_c_r_ls_rs_lfe.mxf
>>>
>>>  Good idea, can someone with access please upload these to the fate mxf
>>>  folder?
>>>
>>>  [...]
>>>
>>>>  I suggest adding the following audio channels, which are specified in
>>>>  SMPTE ST 2067-8 [1] and have a direct mapping to ffmpeg audio
>>>>  channels:AV_CH_STEREO_LEFT
>>>>
>>>>  urn:smpte:ul:060e2b34.0401010d.03020120.03000000 (Left Total) ->
>>>>  AV_CH_STEREO_LEFT
>>>>  urn:smpte:ul:060e2b34.0401010d.03020120.04000000 (RightTotal) ->
>>>>  AV_CH_STEREO_RIGHT
>>>>
>>>>  [1] https://registry.smpte-ra.org/view/published/labels_view.html
>>>
>>>  Unfortunately this is a Dolby encoded stereo mix, not an ordinary
>>>  LeftOnly
>>>  / RightOnly mix. So I am not how this should be signalled.
>>
>>  My interpretation below.
>>
>>  In "mov_chan.c", AV_CH_LAYOUT_STEREO_DOWNMIX means
>>  MOV_CH_LAYOUT_MATRIXSTEREO [1], which is defined in Core Audio [2].
>>
>>  LtRt, i.e. matrix-encoded audio, is not generally Dolby-specific [3].
>>
>>  [1]
>>  https://github.com/FFmpeg/FFmpeg/blob/d6b2357eddca392ee137cb2a92ff178a0a7d0cce/libavformat/mov_chan.c#L168
>>  [2]
>>  https://developer.apple.com/documentation/coreaudiotypes/1572101-audio_channel_layout_tags/kaudiochannellayouttag_matrixstereo?changes=_8_7&language=objc
>>  [3] https://en.wikipedia.org/wiki/Matrix_decoder
>
> Well, ok, I will add these two labels then before pushing.

Will push and backport this tomorrow.

Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-01-08 18:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-01 19:26 [FFmpeg-devel] [PATCH] avformat/mxfdec: support MCA audio information Marton Balint
2022-01-01 23:13 ` Pierre-Anthony Lemieux
2022-01-02  1:11   ` Marton Balint
2022-01-02  2:16     ` Pierre-Anthony Lemieux
2022-01-02 10:26       ` Marton Balint
2022-01-08 18:48         ` Marton Balint
2022-01-02 17:35     ` Michael Niedermayer
2022-01-02  1:35   ` Andreas Rheinhardt
2022-01-02  1:54     ` Pierre-Anthony Lemieux
2022-01-02 10:33       ` Marton Balint
2022-01-03  7:12       ` Andreas Rheinhardt
2022-01-04  4:38         ` Pierre-Anthony Lemieux

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git