PR #20504 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20504
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20504.patch

Marking this as WIP because I think it may be a little contentious. Mainly 
leaving it here as an RFC.


>From 1418fcfe7d326ac9c1b876757f9975e5ac875503 Mon Sep 17 00:00:00 2001
From: Niklas Haas <g...@haasn.dev>
Date: Fri, 12 Sep 2025 17:02:01 +0200
Subject: [PATCH 1/2] avformat/ffprobe: also print alpha_mode on streams

---
 fftools/ffprobe.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index 89b8dd3802..4bb317a535 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -1810,6 +1810,7 @@ static int show_stream(AVTextFormatContext *tfc, 
AVFormatContext *fmt_ctx, int s
         print_color_trc(tfc, par->color_trc);
         print_primaries(tfc, par->color_primaries);
         print_chroma_location(tfc, par->chroma_location);
+        print_alpha_mode(tfc, par->alpha_mode);
 
         if (par->field_order == AV_FIELD_PROGRESSIVE)
             print_str("field_order", "progressive");
-- 
2.49.1


>From 60c21482fa59648d44562731b4542f446643a426 Mon Sep 17 00:00:00 2001
From: Niklas Haas <g...@haasn.dev>
Date: Fri, 12 Sep 2025 17:06:12 +0200
Subject: [PATCH 2/2] avformat/mxf: add custom tagging for alpha mode

Introduce a private UL for this. To avoid conflict, I chose the prefix as
the bytes 'lavf', which should hopefully be unique enough among MXF
implementations.

The full byte sequence for the UL corresponds to:
  lavf meta 0000 alpm
---
 libavformat/mxfdec.c | 18 ++++++++++++++++++
 libavformat/mxfenc.c |  7 +++++++
 2 files changed, 25 insertions(+)

diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index dc5dff651a..26ed917000 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -230,6 +230,7 @@ typedef struct MXFDescriptor {
     size_t mastering_size;
     AVContentLightMetadata *coll;
     size_t coll_size;
+    int alpha_mode;
 } MXFDescriptor;
 
 typedef struct MXFMCASubDescriptor {
@@ -356,6 +357,7 @@ static const uint8_t mxf_indirect_value_utf16le[]          
= { 0x4c,0x00,0x02,0x
 static const uint8_t mxf_indirect_value_utf16be[]          = { 
0x42,0x01,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01
 };
 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_lavf_meta_alpha_mode[]            = { 
0x6c,0x61,0x76,0x66,0x6d,0x65,0x74,0x61,0x00,0x00,0x00,0x00,0x61,0x6c,0x70,0x6d 
};
 
 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 
};
@@ -1503,6 +1505,9 @@ static int mxf_read_generic_descriptor(void *arg, 
AVIOContext *pb, int tag, int
             }
         }
 
+        if (IS_KLV_KEY(uid, mxf_lavf_meta_alpha_mode))
+            descriptor->alpha_mode = avio_r8(pb);
+
         if (IS_KLV_KEY(uid, mxf_sub_descriptor))
             return mxf_read_strong_ref_array(pb, 
&descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count);
 
@@ -2548,6 +2553,18 @@ static enum AVColorRange mxf_get_color_range(MXFContext 
*mxf, MXFDescriptor *des
     return AVCOL_RANGE_UNSPECIFIED;
 }
 
+static enum AVAlphaMode mxf_get_alpha_mode(MXFContext *mxf, MXFDescriptor 
*descriptor)
+{
+    switch (descriptor->alpha_mode) {
+    case 0x00: return AVALPHA_MODE_UNSPECIFIED;
+    case 0x01: return AVALPHA_MODE_PREMULTIPLIED;
+    case 0x02: return AVALPHA_MODE_STRAIGHT;
+    default:
+        avpriv_request_sample(mxf->fc, "Unrecognized alpha mode %d", 
descriptor->alpha_mode);
+        return AVALPHA_MODE_UNSPECIFIED;
+    }
+}
+
 static int is_pcm(enum AVCodecID codec_id)
 {
     /* we only care about "normal" PCM codecs until we get samples */
@@ -3037,6 +3054,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
             st->codecpar->color_primaries = 
mxf_get_codec_ul(ff_mxf_color_primaries_uls, 
&descriptor->color_primaries_ul)->id;
             st->codecpar->color_trc       = 
mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id;
             st->codecpar->color_space     = 
mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id;
+            st->codecpar->alpha_mode      = mxf_get_alpha_mode(mxf, 
descriptor);
             if (descriptor->mastering) {
                 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, 
&st->codecpar->nb_coded_side_data,
                                              
AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index b14a480ba3..9c8db96f44 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -447,6 +447,8 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = {
     { 0x840A, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0A,0x00,0x00,0x00}},
 /* Csiz: The number of components in the picture */
     { 0x840B, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0B,0x00,0x00,0x00}},
 /* Ssizi, XRSizi, YRSizi: Array of picture components where each component 
comprises 3 bytes named Ssizi, XRSizi, YRSizi.  The array of 3-byte groups is 
preceded by the array header comprising a 4-byte value of the number of 
components followed by a 4-byte value of 3. */
     { 0x840C, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0E,0x00,0x00,0x00}},
 /* The nature and order of the image components in the compressed domain as 
carried in the J2C codestream. */
+    // libavformat private tags
+    { 0x8500, 
{0x6c,0x61,0x76,0x66,0x6d,0x65,0x74,0x61,0x00,0x00,0x00,0x00,0x61,0x6c,0x70,0x6d}},
 /* AlphaMode */
 };
 
 #define MXF_NUM_TAGS FF_ARRAY_ELEMS(mxf_local_tag_batch)
@@ -1398,6 +1400,11 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, 
AVStream *st, const UID
         avio_write(pb, color_space_ul->uid, 16);
     };
 
+    if (av_pix_fmt_desc_get(st->codecpar->format)->flags & 
AV_PIX_FMT_FLAG_ALPHA) {
+        mxf_write_local_tag(s, 1, 0x8500);
+        avio_w8(pb, st->codecpar->alpha_mode);
+    }
+
     mxf_write_local_tag(s, 16, 0x3201);
     avio_write(pb, *sc->codec_ul, 16);
 
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-le...@ffmpeg.org

Reply via email to