[FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA
Pierre-Anthony Lemieux
pal at sandflow.com
Sun Apr 23 04:07:53 EEST 2023
On Wed, Mar 29, 2023 at 1:54 PM Cédric Le Barz <clebarz at ektacom.com> wrote:
>
> 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. */
Please add to the comment the symbol and type of the attribute as
specified in the SMPTE registers [1] -- it makes it easier to
review/debug.
In the case above, it would be Riz (UInt16).
[1] https://registry.smpte-ra.org/view/published/elements_by_group_view.html
> + { 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);
It looks like Rsiz is always set to 0, regardless of the contents of
the JPEG 2000 codestreams. Is that correct?
If so, the items of the JPEG 2000 picture sub-descriptor should be set
according to the contents of the JPEG 2000 codestreams. This is
important since items like Rsiz signal profiles, and may result in
decoders fast-failing.
> + 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
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list