Le 05/04/2023 à 15:53, Tomas Härdin a écrit :
ons 2023-04-05 klockan 15:05 +0200 skrev Cédric Le Barz:
Le 03/04/2023 à 17:14, Michael Niedermayer a écrit :
On Mon, Apr 03, 2023 at 10:08:25AM +0200, Cédric Le Barz wrote:
Hi,

I've attached the patch to this mail, in order to solve newlines
insertion
issue.
Please make sure each patch also updates the fate tests so
make fate
doesnt fail
I've attached to this mail the new patch. Fate test issue is fixed.

Please avoid top posting.

I was actually about to suggest merging these two patches but I see you
read my mind :)

@@ -1131,9 +1164,9 @@ static const UID mxf_aes3_descriptor_key      =
{ 0x06,0x0E,0x2B,0x34,0x02,0x53,
  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_rgba_descriptor_key      = {
0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01
,0x29,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 };
-
Stray line deletion

+    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);
A comment on each of these explaining what they are would be nice.

+    {
+        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);
+        }
+    }
Maybe just a style nit but you could move the char desc[] into the loop
body, int comp to the start of the function and then you can remove the
extra {} around this. Also you could make desc static const.

+    {
+        char _layout[16] = {  'Y' , '\n', 'U' , '\n', 'V' , '\n',
'F' , 0x02,
+                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00 };
+        avio_write(pb, _layout , 16);
+    }
Again there is the issue of RGB(A)

/Tomas

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

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


Please consider this new patch taking into account remarks. For the moment, I remove the RGB(A) / YUV code part as it is an optional feature for the JPEG2000 subdescriptor.

Regards,

Cédric
--- Begin Message ---
Signed-off-by: Cedric Le Barz <cleb...@ektacom.com>
---
 ffmpeg/libavformat/mxf.h    |   1 +
 ffmpeg/libavformat/mxfenc.c | 169 +++++++++++++++++++++++++++++++++++-
 2 files changed, 167 insertions(+), 3 deletions(-)

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..7065a7d 100644
--- a/ffmpeg/libavformat/mxfenc.c
+++ b/ffmpeg/libavformat/mxfenc.c
@@ -48,8 +48,10 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/time_internal.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
 #include "libavcodec/golomb.h"
 #include "libavcodec/h264.h"
+#include "libavcodec/jpeg2000.h"
 #include "libavcodec/packet_internal.h"
 #include "libavcodec/startcode.h"
 #include "avformat.h"
@@ -102,6 +104,16 @@ typedef struct MXFStreamContext {
     int b_picture_count;     ///< maximum number of consecutive b pictures, 
used in mpeg-2 descriptor
     int low_delay;           ///< low delay, used in mpeg-2 descriptor
     int avc_intra;
+    uint16_t j2k_cap;        ///< j2k required decoder capabilities
+    uint32_t j2k_xsiz;       ///< j2k widht of the reference grid
+    uint32_t j2k_ysiz;       ///< j2k height of the reference grid
+    uint32_t j2k_x0siz;      ///< j2k horizontal offset from the origin of the 
reference grid to the left side of the image
+    uint32_t j2k_y0siz;      ///< j2k vertical offset from the origin of the 
reference grid to the left side of the image
+    uint32_t j2k_xtsiz;      ///< j2k width of one reference tile with respect 
to the reference grid
+    uint32_t j2k_ytsiz;      ///< j2k height of one reference tile with 
respect to the reference grid
+    uint32_t j2k_xt0siz;     ///< j2k horizontal offset from the origin of the 
reference grid to the left side of the first tile
+    uint32_t j2k_yt0siz;     ///< j2k vertical offset from the origin of the 
reference grid to the left side of the first tile
+    uint8_t  j2k_comp_desc[12]; ///< j2k components descriptor
 } MXFStreamContext;
 
 typedef struct MXFContainerEssenceEntry {
@@ -390,6 +402,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}},
 /* 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}},
 /* Width of the reference grid */
+    { 0x8403, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x03,0x00,0x00,0x00}},
 /* Height of the reference grid */
+    { 0x8404, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x04,0x00,0x00,0x00}},
 /* 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}},
 /* 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}},
 /* 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}},
 /* 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}},
 /* 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}},
 /* 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}},
 /* The number of components in the picture */
+    { 0x840B, 
{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0B,0x00,0x00,0x00}},
 /* 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)
@@ -526,7 +552,7 @@ static void mxf_write_primer_pack(AVFormatContext *s)
     MXFContext *mxf = s->priv_data;
     AVIOContext *pb = s->pb;
     int local_tag_number = MXF_NUM_TAGS, i;
-    int will_have_avc_tags = 0, will_have_mastering_tags = 0;
+    int will_have_avc_tags = 0, will_have_mastering_tags = 0, 
will_have_jpeg2000_tags = 0;
 
     for (i = 0; i < s->nb_streams; i++) {
         MXFStreamContext *sc = s->streams[i]->priv_data;
@@ -536,6 +562,9 @@ static void mxf_write_primer_pack(AVFormatContext *s)
         if (av_stream_get_side_data(s->streams[i], 
AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL)) {
             will_have_mastering_tags = 1;
         }
+        if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_JPEG2000){
+            will_have_jpeg2000_tags = 1;
+        }
     }
 
     if (!mxf->store_user_comments) {
@@ -558,6 +587,22 @@ static void mxf_write_primer_pack(AVFormatContext *s)
         mxf_mark_tag_unused(mxf, 0x8304);
     }
 
+    if (!will_have_jpeg2000_tags) {
+        mxf_mark_tag_unused(mxf, 0x8400);
+        mxf_mark_tag_unused(mxf, 0x8401);
+        mxf_mark_tag_unused(mxf, 0x8402);
+        mxf_mark_tag_unused(mxf, 0x8403);
+        mxf_mark_tag_unused(mxf, 0x8404);
+        mxf_mark_tag_unused(mxf, 0x8405);
+        mxf_mark_tag_unused(mxf, 0x8406);
+        mxf_mark_tag_unused(mxf, 0x8407);
+        mxf_mark_tag_unused(mxf, 0x8408);
+        mxf_mark_tag_unused(mxf, 0x8409);
+        mxf_mark_tag_unused(mxf, 0x840A);
+        mxf_mark_tag_unused(mxf, 0x840B);
+        mxf_mark_tag_unused(mxf, 0x840C);
+    }
+
     for (i = 0; i < MXF_NUM_TAGS; i++) {
         if (mxf->unused_tags[i]) {
             local_tag_number--;
@@ -1095,8 +1140,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,0x00};
 
 static inline uint16_t rescale_mastering_chroma(AVRational q)
 {
@@ -1260,7 +1305,6 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, 
AVStream *st, const UID
         f1 *= 2;
     }
 
-
     mxf_write_local_tag(s, 16, 0x320D);
     avio_wb32(pb, 2);
     avio_wb32(pb, 4);
@@ -1365,6 +1409,65 @@ 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)
+{
+    MXFStreamContext *sc = st->priv_data;
+    AVIOContext *pb = s->pb;
+    int64_t pos;
+    int component_count = av_pix_fmt_count_planes(st->codecpar->format);
+    int comp = 0;
+
+    /* JPEG2000 subdescriptor key */
+    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);
+
+    /* Value defining the decoder capabilities */
+    mxf_write_local_tag(s, 2, 0x8401);
+    avio_wb16(pb, sc->j2k_cap);
+    /* Width of the JPEG2000 reference grid */
+    mxf_write_local_tag(s, 4, 0x8402);
+    avio_wb32(pb, st->codecpar->width);
+    /* Height of the JPEG2000 reference grid */
+    mxf_write_local_tag(s, 4, 0x8403);
+    avio_wb32(pb, st->codecpar->height);
+    /* Horizontal offset from the reference grid origin to the left side of 
the image area */
+    mxf_write_local_tag(s, 4, 0x8404);
+    avio_wb32(pb, sc->j2k_x0siz);
+    /* Vertical offset from the reference grid origin to the left side of the 
image area */
+    mxf_write_local_tag(s, 4, 0x8405);
+    avio_wb32(pb, sc->j2k_y0siz);
+    /* Width of one reference tile with respect to the reference grid */
+    mxf_write_local_tag(s, 4, 0x8406);
+    avio_wb32(pb, sc->j2k_xtsiz);
+    /* Height of one reference tile with respect to the reference grid */
+    mxf_write_local_tag(s, 4, 0x8407);
+    avio_wb32(pb, sc->j2k_ytsiz);
+    /* Horizontal offset from the origin of the reference grid to the left 
side of the first tile */
+    mxf_write_local_tag(s, 4, 0x8408);
+    avio_wb32(pb, sc->j2k_xt0siz);
+    /* Vertical offset from the origin of the reference grid to the left side 
of the first tile */
+    mxf_write_local_tag(s, 4, 0x8409);
+    avio_wb32(pb, sc->j2k_yt0siz);
+    /* Image components number */
+    mxf_write_local_tag(s, 2, 0x840A);
+    avio_wb16(pb, component_count);
+   /* Array of picture components where each component comprises 3 bytes named 
Ssiz(i) (Pixel bitdepth - 1), XRSiz(i) (Horizontal sampling), YRSiz(i) 
(Vertical sampling).
+     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. */
+    mxf_write_local_tag(s, 8 + 3*component_count, 0x840B);
+    avio_wb32(pb, component_count);
+    avio_wb32(pb, 3);
+    for ( comp = 0; comp < component_count; comp++ ) {
+        avio_write(pb, &sc->j2k_comp_desc[3*comp] , 3);
+    }
+
+    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 +1476,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)
@@ -2113,6 +2219,58 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, 
AVStream *st, AVPacket *pkt
     return 1;
 }
 
+static int mxf_parse_jpeg2000_frame(AVFormatContext *s, AVStream *st, AVPacket 
*pkt)
+{
+    MXFContext *mxf = s->priv_data;
+    MXFStreamContext *sc = st->priv_data;
+    int component_count = av_pix_fmt_count_planes(st->codecpar->format);
+    GetByteContext g;
+    uint32_t j2k_ncomponents;
+    int comp;
+
+    if (mxf->header_written)
+        return 1;
+
+    bytestream2_init(&g,pkt->data,pkt->size);
+
+    while (bytestream2_get_bytes_left(&g) >= 3 && bytestream2_peek_be16(&g) != 
JPEG2000_SOC)
+        bytestream2_skip(&g, 1);
+
+    if (bytestream2_get_be16u(&g) != JPEG2000_SOC) {
+        av_log(s, AV_LOG_ERROR, "SOC marker not present\n");
+        return 0;
+    }
+
+    /* Extract usefull size infromation from the SIZ marker */
+    if (bytestream2_get_be16u(&g) != JPEG2000_SIZ) {
+        av_log(s, AV_LOG_ERROR, "SIZ marker not present\n");
+        return 0;
+    }
+    bytestream2_skip(&g, 2); // Skip Lsiz
+    sc->j2k_cap = bytestream2_get_be16u(&g);
+    sc->j2k_xsiz = bytestream2_get_be32u(&g);
+    sc->j2k_ysiz = bytestream2_get_be32u(&g);
+    sc->j2k_x0siz = bytestream2_get_be32u(&g);
+    sc->j2k_y0siz = bytestream2_get_be32u(&g);
+    sc->j2k_xtsiz = bytestream2_get_be32u(&g);
+    sc->j2k_ytsiz = bytestream2_get_be32u(&g);
+    sc->j2k_xt0siz = bytestream2_get_be32u(&g);
+    sc->j2k_yt0siz = bytestream2_get_be32u(&g);
+    j2k_ncomponents = bytestream2_get_be16u(&g);
+    if (j2k_ncomponents != component_count) {
+        av_log(s, AV_LOG_WARNING, "Incoherence about components image 
number.\n");
+    }
+    for (comp = 0; comp < j2k_ncomponents; comp++) {
+        sc->j2k_comp_desc[comp*j2k_ncomponents] = bytestream2_get_byteu(&g);   
// Bitdepth for each component
+        sc->j2k_comp_desc[comp*j2k_ncomponents+1] = bytestream2_get_byteu(&g); 
// Horizontal sampling for each component
+        sc->j2k_comp_desc[comp*j2k_ncomponents+2] = bytestream2_get_byteu(&g); 
// Vertical sampling for each component
+    }
+
+    sc->frame_size = pkt->size;
+
+    return 1;
+}
+
 static const struct {
     const UID container_ul;
     const UID codec_ul;
@@ -2958,6 +3116,11 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket 
*pkt)
             av_log(s, AV_LOG_ERROR, "could not get h264 profile\n");
             return -1;
         }
+    } else if (st->codecpar->codec_id == AV_CODEC_ID_JPEG2000) {
+        if (!mxf_parse_jpeg2000_frame(s, st, pkt)) {
+            av_log(s, AV_LOG_ERROR, "could not get jpeg2000 profile\n");
+            return -1;
+        }
     }
 
     if (mxf->cbr_index) {
-- 
2.34.1


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

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

Reply via email to