[FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA

Cédric Le Barz clebarz at ektacom.com
Wed Mar 29 23:54:39 EEST 2023


Add jpeg2000 subdescriptor in MXF file.

Signed-off-by: Cedric Le Barz <clebarz at ektacom.com>
---
  ffmpeg/libavformat/mxf.h    |  1 +
  ffmpeg/libavformat/mxfenc.c | 74 ++++++++++++++++++++++++++++++++++++-
  2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/ffmpeg/libavformat/mxf.h b/ffmpeg/libavformat/mxf.h
index 2561605..7dd1681 100644
--- a/ffmpeg/libavformat/mxf.h
+++ b/ffmpeg/libavformat/mxf.h
@@ -55,6 +55,7 @@ enum MXFMetadataSetType {
      SoundfieldGroupLabelSubDescriptor,
      GroupOfSoundfieldGroupsLabelSubDescriptor,
      FFV1SubDescriptor,
+    JPEG2000SubDescriptor,
  };
   enum MXFFrameLayout {
diff --git a/ffmpeg/libavformat/mxfenc.c b/ffmpeg/libavformat/mxfenc.c
index a29d678..3bdf90a 100644
--- a/ffmpeg/libavformat/mxfenc.c
+++ b/ffmpeg/libavformat/mxfenc.c
@@ -390,6 +390,20 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = {
      { 0x8302, FF_MXF_MasteringDisplayWhitePointChromaticity },
      { 0x8303, FF_MXF_MasteringDisplayMaximumLuminance },
      { 0x8304, FF_MXF_MasteringDisplayMinimumLuminance },
+    // ff_mxf_jpeg2000_local_tags
+    { 0x8400, 
{0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00}}, 
/* Sub Descriptors / Opt Ordered array of strong references to sub 
descriptor sets */
+    { 0x8401, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x01,0x00,0x00,0x00}}, 
/* 2 bytes : An enumerated value that defines the decoder capabilities.  */
+    { 0x8402, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x02,0x00,0x00,0x00}}, 
/* 4 bytes : Width of the reference grid */
+    { 0x8403, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x03,0x00,0x00,0x00}}, 
/* 4 bytes : Height of the reference grid */
+    { 0x8404, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x04,0x00,0x00,0x00}}, 
/* 4 bytes : Horizontal offset from the origin of the reference grid to 
the left side of the image area */
+    { 0x8405, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x05,0x00,0x00,0x00}}, 
/* 4 bytes : Vertical offset from the origin of the reference grid to 
the left side of the image area */
+    { 0x8406, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x06,0x00,0x00,0x00}}, 
/* 4 bytes : Width of one reference tile with respect to the reference 
grid, */
+    { 0x8407, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x07,0x00,0x00,0x00}}, 
/* 4 bytes : Height of one reference tile with respect to the reference 
grid, */
+    { 0x8408, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x08,0x00,0x00,0x00}}, 
/* 4 bytes : Horizontal offset from the origin of the reference grid to 
the left side of the first tile */
+    { 0x8409, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x09,0x00,0x00,0x00}}, 
/* 4 bytes : Vertical offset from the origin of the reference grid to 
the left side of the first tile */
+    { 0x840A, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0A,0x00,0x00,0x00}}, 
/* 2 bytes : The number of components in the picture */
+    { 0x840B, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0B,0x00,0x00,0x00}}, 
/* 8+3n bytes : 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.. */
  };
   #define MXF_NUM_TAGS FF_ARRAY_ELEMS(mxf_local_tag_batch)
@@ -1095,8 +1109,8 @@ static const UID mxf_wav_descriptor_key       = { 
0x06,0x0E,0x2B,0x34,0x02,0x53,
  static const UID mxf_aes3_descriptor_key      = { 
0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 
};
  static const UID mxf_cdci_descriptor_key      = { 
0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 
};
  static const UID mxf_generic_sound_descriptor_key = { 
0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 
};
-
  static const UID mxf_avc_subdescriptor_key = { 
0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6E,0x00 
};
+static const UID mxf_jpeg2000_subdescriptor_key   = { 
0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x5A,00 
};
   static inline uint16_t rescale_mastering_chroma(AVRational q)
  {
@@ -1365,6 +1379,60 @@ static void mxf_write_avc_subdesc(AVFormatContext 
*s, AVStream *st)
      mxf_update_klv_size(s->pb, pos);
  }
  +static void mxf_write_jpeg2000_subdesc(AVFormatContext *s, AVStream *st)
+{
+    AVIOContext *pb = s->pb;
+    int64_t pos;
+
+    int component_count = av_pix_fmt_count_planes(st->codecpar->format);
+
+    avio_write(pb, mxf_jpeg2000_subdescriptor_key, 16);
+    klv_encode_ber4_length(pb, 0);
+    pos = avio_tell(pb);
+
+    mxf_write_local_tag(s, 16, 0x3C0A);
+    mxf_write_uuid(pb, JPEG2000SubDescriptor, 0);
+
+    mxf_write_local_tag(s, 2, 0x8401);
+    avio_wb16(pb, 0x0000);
+    mxf_write_local_tag(s, 4, 0x8402);
+    avio_wb32(pb, st->codecpar->width);
+    mxf_write_local_tag(s, 4, 0x8403);
+    avio_wb32(pb, st->codecpar->height);
+    mxf_write_local_tag(s, 4, 0x8404);
+    avio_wb32(pb, 0);
+    mxf_write_local_tag(s, 4, 0x8405);
+    avio_wb32(pb, 0);
+    mxf_write_local_tag(s, 4, 0x8406);
+    avio_wb32(pb, st->codecpar->width);
+    mxf_write_local_tag(s, 4, 0x8407);
+    avio_wb32(pb, st->codecpar->height);
+    mxf_write_local_tag(s, 4, 0x8408);
+    avio_wb32(pb, 0);
+    mxf_write_local_tag(s, 4, 0x8409);
+    avio_wb32(pb, 0);
+    mxf_write_local_tag(s, 2, 0x840A);
+    avio_wb16(pb, component_count);
+
+    mxf_write_local_tag(s, 8 + 3*component_count, 0x840B);
+    avio_wb32(pb, component_count);
+    avio_wb32(pb, 3);
+    {
+        char _desc [3][3]= {  {0x09,0x01,0x01} , {0x09,0x02,0x01} , 
{0x09,0x02,0x01} };
+        int comp = 0;
+        for ( comp = 0; comp< component_count ;comp++ ) {
+            avio_write(pb, _desc[comp%3] , 3);
+        }
+    }
+    mxf_write_local_tag(s, 16, 0x840C);
+    {
+        char _layout[16] = {  'Y' , '\n', 'U' , '\n', 'V' , '\n', 'F' , 
0x02,
+                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00 };
+        avio_write(pb, _layout , 16);
+    }
+    mxf_update_klv_size(pb, pos);
+}
+
  static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
  {
      int64_t pos = mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key);
@@ -1373,6 +1441,9 @@ static void mxf_write_cdci_desc(AVFormatContext 
*s, AVStream *st)
      if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
          mxf_write_avc_subdesc(s, st);
      }
+    if (st->codecpar->codec_id == AV_CODEC_ID_JPEG2000) {
+         mxf_write_jpeg2000_subdesc(s, st);
+    }
  }
   static void mxf_write_h264_desc(AVFormatContext *s, AVStream *st)
@@ -3311,3 +3382,4 @@ const FFOutputFormat ff_mxf_opatom_muxer = {
      .interleave_packet = mxf_interleave,
      .p.priv_class      = &mxf_opatom_muxer_class,
  };
+
-- 
2.34.1



More information about the ffmpeg-devel mailing list