* [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA @ 2023-03-29 20:54 Cédric Le Barz 2023-03-31 21:47 ` Michael Niedermayer 2023-04-23 1:07 ` Pierre-Anthony Lemieux 0 siblings, 2 replies; 16+ messages in thread From: Cédric Le Barz @ 2023-03-29 20:54 UTC (permalink / raw) To: ffmpeg-devel Add jpeg2000 subdescriptor in MXF file. Signed-off-by: Cedric Le Barz <clebarz@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 _______________________________________________ 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-03-29 20:54 [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA Cédric Le Barz @ 2023-03-31 21:47 ` Michael Niedermayer 2023-04-03 8:08 ` Cédric Le Barz 2023-04-23 1:07 ` Pierre-Anthony Lemieux 1 sibling, 1 reply; 16+ messages in thread From: Michael Niedermayer @ 2023-03-31 21:47 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1.1: Type: text/plain, Size: 1881 bytes --] On Wed, Mar 29, 2023 at 10:54:39PM +0200, Cédric Le Barz wrote: > Add jpeg2000 subdescriptor in MXF file. > > Signed-off-by: Cedric Le Barz <clebarz@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 */ your patch is corrupted by newlines, i suggest you check word/line wraping settings or attach it instead thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The real ebay dictionary, page 1 "Used only once" - "Some unspecified defect prevented a second use" "In good condition" - "Can be repaird by experienced expert" "As is" - "You wouldnt want it even if you were payed for it, if you knew ..." [-- 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-03-31 21:47 ` Michael Niedermayer @ 2023-04-03 8:08 ` Cédric Le Barz 2023-04-03 15:14 ` Michael Niedermayer 2023-04-05 12:39 ` Tomas Härdin 0 siblings, 2 replies; 16+ messages in thread From: Cédric Le Barz @ 2023-04-03 8:08 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 2071 bytes --] Hi, I've attached the patch to this mail, in order to solve newlines insertion issue. Regards, Cédric Le 31/03/2023 à 23:47, Michael Niedermayer a écrit : > On Wed, Mar 29, 2023 at 10:54:39PM +0200, Cédric Le Barz wrote: >> Add jpeg2000 subdescriptor in MXF file. >> >> Signed-off-by: Cedric Le Barz <clebarz@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,0x0 > 0,0x00}}, >> /* Sub Descriptors / Opt Ordered array of strong references to sub >> descriptor sets */ > your patch is corrupted by newlines, i suggest you check word/line wraping > settings or attach it instead > > thx > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > The real ebay dictionary, page 1 > "Used only once" - "Some unspecified defect prevented a second use" > "In good condition" - "Can be repaird by experienced expert" > "As is" - "You wouldnt want it even if you were payed for it, if you knew > ..." [-- Attachment #2: 0001-Add-jpeg2000-subdescriptor.eml --] [-- Type: message/rfc822, Size: 7300 bytes --] From: Cedric Le Barz <clebarz@ektacom.com> To: ffmpeg-devel@ffmpeg.org Subject: [PATCH] Add jpeg2000 subdescriptor. Date: Wed, 29 Mar 2023 22:46:40 +0200 Signed-off-by: Cedric Le Barz <clebarz@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 [-- Attachment #3: 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-03 8:08 ` Cédric Le Barz @ 2023-04-03 15:14 ` Michael Niedermayer 2023-04-05 13:05 ` Cédric Le Barz 2023-04-05 12:39 ` Tomas Härdin 1 sibling, 1 reply; 16+ messages in thread From: Michael Niedermayer @ 2023-04-03 15:14 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1.1: Type: text/plain, Size: 413 bytes --] 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 thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB What does censorship reveal? It reveals fear. -- Julian Assange [-- 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-03 15:14 ` Michael Niedermayer @ 2023-04-05 13:05 ` Cédric Le Barz 2023-04-05 13:53 ` Tomas Härdin 0 siblings, 1 reply; 16+ messages in thread From: Cédric Le Barz @ 2023-04-05 13:05 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 564 bytes --] I've attached to this mail the new patch. Fate test issue is fixed. Regards, Cédric 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 > > thx > > [...] > > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > What does censorship reveal? It reveals fear. -- Julian Assange [-- Attachment #2: 0001-Add-jpeg2000-subdescriptor.eml --] [-- Type: message/rfc822, Size: 9168 bytes --] From: Cedric Le Barz <clebarz@ektacom.com> To: ffmpeg-devel@ffmpeg.org Subject: [PATCH] Add jpeg2000 subdescriptor. Date: Wed, 5 Apr 2023 14:57:45 +0200 Signed-off-by: Cedric Le Barz <clebarz@ektacom.com> --- ffmpeg/libavformat/mxf.h | 1 + ffmpeg/libavformat/mxfenc.c | 94 ++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 2 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 9eba208..24bdd03 100644 --- a/ffmpeg/libavformat/mxfenc.c +++ b/ffmpeg/libavformat/mxfenc.c @@ -413,6 +413,20 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = { { 0xDFD9, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x0C,0x06,0x00,0x00,0x00}}, /* FFV1 Micro-version */ { 0xDFDA, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x0C,0x05,0x00,0x00,0x00}}, /* FFV1 Version */ { 0xDFDB, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x0C,0x01,0x00,0x00,0x00}}, /* FFV1 Initialization Metadata */ + // 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) @@ -549,7 +563,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, will_have_ffv1_tags = 0; + int will_have_avc_tags = 0, will_have_mastering_tags = 0, will_have_ffv1_tags = 0, will_have_jpeg2000_tags = 0; for (i = 0; i < s->nb_streams; i++) { MXFStreamContext *sc = s->streams[i]->priv_data; @@ -562,6 +576,9 @@ static void mxf_write_primer_pack(AVFormatContext *s) if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_FFV1) { will_have_ffv1_tags = 1; } + if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_JPEG2000){ + will_have_jpeg2000_tags = 1; + } } if (!mxf->store_user_comments) { @@ -593,6 +610,22 @@ static void mxf_write_primer_pack(AVFormatContext *s) mxf_mark_tag_unused(mxf, 0xDFDB); } + 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--; @@ -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 }; - 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_ffv1_subdescriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x81,0x03 }; +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) { @@ -1426,6 +1459,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); @@ -1434,6 +1521,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) -- 2.34.1 [-- Attachment #3: 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-05 13:05 ` Cédric Le Barz @ 2023-04-05 13:53 ` Tomas Härdin 2023-04-25 14:33 ` Cédric Le Barz 0 siblings, 1 reply; 16+ messages in thread From: Tomas Härdin @ 2023-04-05 13:53 UTC (permalink / raw) To: FFmpeg development discussions and patches 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-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-05 13:53 ` Tomas Härdin @ 2023-04-25 14:33 ` Cédric Le Barz 2023-04-27 12:45 ` Tomas Härdin 0 siblings, 1 reply; 16+ messages in thread From: Cédric Le Barz @ 2023-04-25 14:33 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 3293 bytes --] 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-request@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 [-- Attachment #2: 0001-Add-jpeg2000-subdescriptor-2.eml --] [-- Type: message/rfc822, Size: 14080 bytes --] From: Cedric Le Barz <clebarz@ektacom.com> To: ffmpeg-devel@ffmpeg.org Subject: [PATCH] Add jpeg2000 subdescriptor (2). Date: Wed, 5 Apr 2023 11:59:18 +0200 Signed-off-by: Cedric Le Barz <clebarz@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 [-- Attachment #3: 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-25 14:33 ` Cédric Le Barz @ 2023-04-27 12:45 ` Tomas Härdin 2023-05-02 15:43 ` Cédric Le Barz 0 siblings, 1 reply; 16+ messages in thread From: Tomas Härdin @ 2023-04-27 12:45 UTC (permalink / raw) To: FFmpeg development discussions and patches > 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; > } > > - Stray deleted line > + /* Image components number */ > + mxf_write_local_tag(s, 2, 0x840A); > + avio_wb16(pb, component_count); > + /* Array of picture components where each component comprises 3 Looks like you missed a space there (: > + /* 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"); Erroring out here seems more appropriate. /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-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-27 12:45 ` Tomas Härdin @ 2023-05-02 15:43 ` Cédric Le Barz 2023-05-09 9:49 ` Tomas Härdin 2023-05-09 14:28 ` Pierre-Anthony Lemieux 0 siblings, 2 replies; 16+ messages in thread From: Cédric Le Barz @ 2023-05-02 15:43 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 1877 bytes --] Le 27/04/2023 à 14:45, Tomas Hardin a écrit : >> 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; >> } >> >> - > Stray deleted line > >> + /* Image components number */ >> + mxf_write_local_tag(s, 2, 0x840A); >> + avio_wb16(pb, component_count); >> + /* Array of picture components where each component comprises 3 > Looks like you missed a space there (: > >> + /* 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"); > Erroring out here seems more appropriate. > > /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-request@ffmpeg.org with subject "unsubscribe". I've attached to this mail the new patch taking into account the 3 remarks above. Regards Cédric [-- Attachment #2: 0001-Add-jpeg2000-subdescriptor-3.eml --] [-- Type: message/rfc822, Size: 13868 bytes --] From: Cedric Le Barz <clebarz@ektacom.com> To: ffmpeg-devel@ffmpeg.org Subject: [PATCH] Add jpeg2000 subdescriptor. Date: Wed, 5 Apr 2023 11:59:18 +0200 Signed-off-by: Cedric Le Barz <clebarz@ektacom.com> --- ffmpeg/libavformat/mxf.h | 1 + ffmpeg/libavformat/mxfenc.c | 169 +++++++++++++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 2 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..909682a 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) { @@ -1365,6 +1410,66 @@ 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 +1478,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 +2221,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_ERROR, "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 +3118,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 [-- Attachment #3: 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-05-02 15:43 ` Cédric Le Barz @ 2023-05-09 9:49 ` Tomas Härdin 2023-05-09 14:28 ` Pierre-Anthony Lemieux 1 sibling, 0 replies; 16+ messages in thread From: Tomas Härdin @ 2023-05-09 9:49 UTC (permalink / raw) To: FFmpeg development discussions and patches > + if (j2k_ncomponents != component_count) { > + av_log(s, AV_LOG_ERROR, "Incoherence about components image > number.\n"); > + } I still think you should error out here, since mismatched component count is indicative of broken internal logic /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-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-05-02 15:43 ` Cédric Le Barz 2023-05-09 9:49 ` Tomas Härdin @ 2023-05-09 14:28 ` Pierre-Anthony Lemieux 2023-06-01 15:19 ` Cédric Le Barz 1 sibling, 1 reply; 16+ messages in thread From: Pierre-Anthony Lemieux @ 2023-05-09 14:28 UTC (permalink / raw) To: FFmpeg development discussions and patches Couple of follow-up comments. - "mxf_parse_jpeg2000_frame" could be moved to one of jpeg2000 source files, to keep J2K parsing code together. Maybe there is a way to reuse jpeg2000_read_main_headers() at jpeg2000dec.c? - when defining the J2K descriptor items, please refer to the symbol name from the SMPTE registers, it make following/debugging the code a lot easier: { 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 */ becomes { 0x8405, {0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x05,0x00,0x00,0x00}}, /* YOsiz: vertical offset from the origin of the reference grid to the left side of the image area */ _______________________________________________ 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-05-09 14:28 ` Pierre-Anthony Lemieux @ 2023-06-01 15:19 ` Cédric Le Barz 2023-06-04 18:24 ` Tomas Härdin 0 siblings, 1 reply; 16+ messages in thread From: Cédric Le Barz @ 2023-06-01 15:19 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 2126 bytes --] Le 09/05/2023 à 16:28, Pierre-Anthony Lemieux a écrit : > Couple of follow-up comments. > > - "mxf_parse_jpeg2000_frame" could be moved to one of jpeg2000 source > files, to keep J2K parsing code together. Maybe there is a way to > reuse jpeg2000_read_main_headers() at jpeg2000dec.c? > > - when defining the J2K descriptor items, please refer to the symbol > name from the SMPTE registers, it make following/debugging the code a > lot easier: > > { 0x8405, > {0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x05,0x00,0x0 > 0,0x00}}, > /* Vertical offset from the origin of the reference grid to the left > side of the image area */ > > becomes > > { 0x8405, > {0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x05,0x00,0x0 > 0,0x00}}, > /* YOsiz: vertical offset from the origin of the reference grid to the > left side of the image area */ > _______________________________________________ > 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". Attach to this mail, is my new patch for adding jpeg2000 sub-descriptor in MXF file taking into account remarks from FFmpeg community (remarks from Pierre-Anthony above as well as this from Tomas), i.e. : 1 - When there is a mismatch in components number, this is now process as an error. 2 - When defining and using the J2K descriptor items, I now refer to the symbol name from the SMPTE registers (X0siz, XT0siz...) 3 - As suggested, I make use of jpeg2000_read_main_headers() in libavcodec. But, I let the parsing function in mxfenc.c file as all other parsing functions are in this file (mxf_parse_mpeg2_frame, mxf_parse_h264_frame...). The use of jpeg2000_read_main_headers() in mxfenc implies some minor modifications in jpeg2000 files : * rename of Jpeg2000Tile structure to J2kTile in j2kenc.c (to avoid redefinition) * move some structure declarations from jpeg2000dec.c to jpeg2000.h * make jpeg2000_read_main_headers() function "public" Regards, Cédric [-- Attachment #2: 0001-Add-jpeg2000-subdescriptor-4.eml --] [-- Type: message/rfc822, Size: 28680 bytes --] From: Cedric Le Barz <clebarz@ektacom.com> To: ffmpeg-devel@ffmpeg.org Subject: [PATCH] Add jpeg2000 subdescriptor (take into account FFmpeg community remarks). Date: Wed, 5 Apr 2023 11:59:18 +0200 Signed-off-by: Cedric Le Barz <clebarz@ektacom.com> --- ffmpeg/libavcodec/j2kenc.c | 28 +++--- ffmpeg/libavcodec/jpeg2000.h | 90 +++++++++++++++++ ffmpeg/libavcodec/jpeg2000dec.c | 89 +---------------- ffmpeg/libavformat/mxf.h | 1 + ffmpeg/libavformat/mxfenc.c | 169 +++++++++++++++++++++++++++++++- 5 files changed, 273 insertions(+), 104 deletions(-) diff --git a/ffmpeg/libavcodec/j2kenc.c b/ffmpeg/libavcodec/j2kenc.c index 6406f90..f5178d7 100644 --- a/ffmpeg/libavcodec/j2kenc.c +++ b/ffmpeg/libavcodec/j2kenc.c @@ -106,7 +106,7 @@ static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied typedef struct { Jpeg2000Component *comp; double *layer_rates; -} Jpeg2000Tile; +} J2kTile; typedef struct { AVClass *class; @@ -131,7 +131,7 @@ typedef struct { Jpeg2000CodingStyle codsty; Jpeg2000QuantStyle qntsty; - Jpeg2000Tile *tile; + J2kTile *tile; int layer_rates[100]; uint8_t compression_rate_enc; ///< Is compression done using compression ratio? @@ -171,7 +171,7 @@ static void dump(Jpeg2000EncoderContext *s, FILE *fd) s->width, s->height, s->tile_width, s->tile_height, s->numXtiles, s->numYtiles, s->ncomponents); for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - Jpeg2000Tile *tile = s->tile + tileno; + J2kTile *tile = s->tile + tileno; nspaces(fd, 2); fprintf(fd, "tile %d:\n", tileno); for(compno = 0; compno < s->ncomponents; compno++){ @@ -427,7 +427,7 @@ static void compute_rates(Jpeg2000EncoderContext* s) int layno, compno; for (i = 0; i < s->numYtiles; i++) { for (j = 0; j < s->numXtiles; j++) { - Jpeg2000Tile *tile = &s->tile[s->numXtiles * i + j]; + J2kTile *tile = &s->tile[s->numXtiles * i + j]; for (compno = 0; compno < s->ncomponents; compno++) { int tilew = tile->comp[compno].coord[0][1] - tile->comp[compno].coord[0][0]; int tileh = tile->comp[compno].coord[1][1] - tile->comp[compno].coord[1][0]; @@ -460,12 +460,12 @@ static int init_tiles(Jpeg2000EncoderContext *s) s->numXtiles = ff_jpeg2000_ceildiv(s->width, s->tile_width); s->numYtiles = ff_jpeg2000_ceildiv(s->height, s->tile_height); - s->tile = av_calloc(s->numXtiles, s->numYtiles * sizeof(Jpeg2000Tile)); + s->tile = av_calloc(s->numXtiles, s->numYtiles * sizeof(J2kTile)); if (!s->tile) return AVERROR(ENOMEM); for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++) for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){ - Jpeg2000Tile *tile = s->tile + tileno; + J2kTile *tile = s->tile + tileno; tile->comp = av_calloc(s->ncomponents, sizeof(*tile->comp)); if (!tile->comp) @@ -509,7 +509,7 @@ static int init_tiles(Jpeg2000EncoderContext *s) int tileno, compno, i, y, x; \ const PIXEL *line; \ for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ \ - Jpeg2000Tile *tile = s->tile + tileno; \ + J2kTile *tile = s->tile + tileno; \ if (s->planar){ \ for (compno = 0; compno < s->ncomponents; compno++){ \ Jpeg2000Component *comp = tile->comp + compno; \ @@ -701,7 +701,7 @@ static void encode_clnpass(Jpeg2000T1Context *t1, int width, int height, int ban } } -static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, Jpeg2000Tile *tile, +static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, J2kTile *tile, int width, int height, int bandpos, int lev) { int pass_t = 2, passno, x, y, max=0, nmsedec, bpno; @@ -935,7 +935,7 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in return 0; } -static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno, int nlayers) +static int encode_packets(Jpeg2000EncoderContext *s, J2kTile *tile, int tileno, int nlayers) { int compno, reslevelno, layno, ret; Jpeg2000CodingStyle *codsty = &s->codsty; @@ -1181,7 +1181,7 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til return 0; } -static void makelayer(Jpeg2000EncoderContext *s, int layno, double thresh, Jpeg2000Tile* tile, int final) +static void makelayer(Jpeg2000EncoderContext *s, int layno, double thresh, J2kTile* tile, int final) { int compno, resno, bandno, precno, cblkno; int passno; @@ -1264,7 +1264,7 @@ static void makelayer(Jpeg2000EncoderContext *s, int layno, double thresh, Jpeg2 } } -static void makelayers(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) +static void makelayers(Jpeg2000EncoderContext *s, J2kTile *tile) { int precno, compno, reslevelno, bandno, cblkno, lev, passno, layno; int i; @@ -1365,7 +1365,7 @@ static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) return res; } -static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) +static void truncpasses(Jpeg2000EncoderContext *s, J2kTile *tile) { int precno, compno, reslevelno, bandno, cblkno, lev; Jpeg2000CodingStyle *codsty = &s->codsty; @@ -1399,7 +1399,7 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) } } -static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno) +static int encode_tile(Jpeg2000EncoderContext *s, J2kTile *tile, int tileno) { int compno, reslevelno, bandno, ret; Jpeg2000T1Context t1; @@ -1514,7 +1514,7 @@ static void reinit(Jpeg2000EncoderContext *s) { int tileno, compno; for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - Jpeg2000Tile *tile = s->tile + tileno; + J2kTile *tile = s->tile + tileno; for (compno = 0; compno < s->ncomponents; compno++) ff_jpeg2000_reinit(tile->comp + compno, &s->codsty); } diff --git a/ffmpeg/libavcodec/jpeg2000.h b/ffmpeg/libavcodec/jpeg2000.h index e5ecb4c..e1ebca5 100644 --- a/ffmpeg/libavcodec/jpeg2000.h +++ b/ffmpeg/libavcodec/jpeg2000.h @@ -33,7 +33,9 @@ #include "avcodec.h" #include "mqc.h" +#include "bytestream.h" #include "jpeg2000dwt.h" +#include "jpeg2000dsp.h" enum Jpeg2000Markers { JPEG2000_SOC = 0xff4f, // start of codestream @@ -120,6 +122,8 @@ enum Jpeg2000Quantsty { // quantization style #define JPEG2000_PGOD_PCRL 0x03 // Position-component-resolution level-layer progression #define JPEG2000_PGOD_CPRL 0x04 // Component-position-resolution level-layer progression +#define MAX_POCS 32 + typedef struct Jpeg2000T1Context { int data[6144]; uint16_t flags[6156]; @@ -227,6 +231,90 @@ typedef struct Jpeg2000Component { uint8_t roi_shift; // ROI scaling value for the component } Jpeg2000Component; + +typedef struct Jpeg2000POCEntry { + uint16_t LYEpoc; + uint16_t CSpoc; + uint16_t CEpoc; + uint8_t RSpoc; + uint8_t REpoc; + uint8_t Ppoc; +} Jpeg2000POCEntry; + +typedef struct Jpeg2000POC { + Jpeg2000POCEntry poc[MAX_POCS]; + int nb_poc; + int is_default; +} Jpeg2000POC; + +typedef struct Jpeg2000TilePart { + uint8_t tile_index; // Tile index who refers the tile-part + const uint8_t *tp_end; + GetByteContext header_tpg; // bit stream of header if PPM header is used + GetByteContext tpg; // bit stream in tile-part +} Jpeg2000TilePart; + +typedef struct Jpeg2000Tile { + Jpeg2000Component *comp; + uint8_t properties[4]; + Jpeg2000CodingStyle codsty[4]; + Jpeg2000QuantStyle qntsty[4]; + Jpeg2000POC poc; + Jpeg2000TilePart tile_part[32]; + uint8_t has_ppt; // whether this tile has a ppt marker + uint8_t *packed_headers; // contains packed headers. Used only along with PPT marker + int packed_headers_size; // size in bytes of the packed headers + GetByteContext packed_headers_stream; // byte context corresponding to packed headers + uint16_t tp_idx; // Tile-part index + int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} +} Jpeg2000Tile; + +typedef struct Jpeg2000DecoderContext { + AVClass *class; + AVCodecContext *avctx; + GetByteContext g; + + int width, height; + int image_offset_x, image_offset_y; + int tile_offset_x, tile_offset_y; + uint8_t cbps[4]; // bits per sample in particular components + uint8_t sgnd[4]; // if a component is signed + uint8_t properties[4]; + + uint8_t has_ppm; + uint8_t *packed_headers; // contains packed headers. Used only along with PPM marker + int packed_headers_size; + GetByteContext packed_headers_stream; + uint8_t in_tile_headers; + + int cdx[4], cdy[4]; + int precision; + int ncomponents; + int colour_space; + uint32_t palette[256]; + int8_t pal8; + int cdef[4]; + int tile_width, tile_height; + unsigned numXtiles, numYtiles; + int maxtilelen; + AVRational sar; + + Jpeg2000CodingStyle codsty[4]; + Jpeg2000QuantStyle qntsty[4]; + Jpeg2000POC poc; + uint8_t roi_shift[4]; + + int bit_index; + + int curtileno; + + Jpeg2000Tile *tile; + Jpeg2000DSPContext dsp; + + // options parameters + int reduction_factor; +} Jpeg2000DecoderContext; + /* misc tools */ static inline int ff_jpeg2000_ceildivpow2(int a, int b) { @@ -286,6 +374,8 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty); void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty); +int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s); + static inline int needs_termination(int style, int passno) { if (style & JPEG2000_CBLK_BYPASS) { int type = passno % 3; diff --git a/ffmpeg/libavcodec/jpeg2000dec.c b/ffmpeg/libavcodec/jpeg2000dec.c index c2b81ec..80db484 100644 --- a/ffmpeg/libavcodec/jpeg2000dec.c +++ b/ffmpeg/libavcodec/jpeg2000dec.c @@ -51,93 +51,6 @@ #define HAD_COC 0x01 #define HAD_QCC 0x02 -#define MAX_POCS 32 - -typedef struct Jpeg2000POCEntry { - uint16_t LYEpoc; - uint16_t CSpoc; - uint16_t CEpoc; - uint8_t RSpoc; - uint8_t REpoc; - uint8_t Ppoc; -} Jpeg2000POCEntry; - -typedef struct Jpeg2000POC { - Jpeg2000POCEntry poc[MAX_POCS]; - int nb_poc; - int is_default; -} Jpeg2000POC; - -typedef struct Jpeg2000TilePart { - uint8_t tile_index; // Tile index who refers the tile-part - const uint8_t *tp_end; - GetByteContext header_tpg; // bit stream of header if PPM header is used - GetByteContext tpg; // bit stream in tile-part -} Jpeg2000TilePart; - -/* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile - * one per component, so tile_part elements have a size of 3 */ -typedef struct Jpeg2000Tile { - Jpeg2000Component *comp; - uint8_t properties[4]; - Jpeg2000CodingStyle codsty[4]; - Jpeg2000QuantStyle qntsty[4]; - Jpeg2000POC poc; - Jpeg2000TilePart tile_part[32]; - uint8_t has_ppt; // whether this tile has a ppt marker - uint8_t *packed_headers; // contains packed headers. Used only along with PPT marker - int packed_headers_size; // size in bytes of the packed headers - GetByteContext packed_headers_stream; // byte context corresponding to packed headers - uint16_t tp_idx; // Tile-part index - int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -} Jpeg2000Tile; - -typedef struct Jpeg2000DecoderContext { - AVClass *class; - AVCodecContext *avctx; - GetByteContext g; - - int width, height; - int image_offset_x, image_offset_y; - int tile_offset_x, tile_offset_y; - uint8_t cbps[4]; // bits per sample in particular components - uint8_t sgnd[4]; // if a component is signed - uint8_t properties[4]; - - uint8_t has_ppm; - uint8_t *packed_headers; // contains packed headers. Used only along with PPM marker - int packed_headers_size; - GetByteContext packed_headers_stream; - uint8_t in_tile_headers; - - int cdx[4], cdy[4]; - int precision; - int ncomponents; - int colour_space; - uint32_t palette[256]; - int8_t pal8; - int cdef[4]; - int tile_width, tile_height; - unsigned numXtiles, numYtiles; - int maxtilelen; - AVRational sar; - - Jpeg2000CodingStyle codsty[4]; - Jpeg2000QuantStyle qntsty[4]; - Jpeg2000POC poc; - uint8_t roi_shift[4]; - - int bit_index; - - int curtileno; - - Jpeg2000Tile *tile; - Jpeg2000DSPContext dsp; - - /*options parameters*/ - int reduction_factor; -} Jpeg2000DecoderContext; - /* get_bits functions for JPEG2000 packet bitstream * It is a get_bit function with a bit-stuffing routine. If the value of the * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB. @@ -2134,7 +2047,7 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s) s->ncomponents = 0; } -static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) +int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) { Jpeg2000CodingStyle *codsty = s->codsty; Jpeg2000QuantStyle *qntsty = s->qntsty; 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..aa7dbd7 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_rsiz; ///< j2k required decoder capabilities (Rsiz) + uint32_t j2k_xsiz; ///< j2k widht of the reference grid (Xsiz) + uint32_t j2k_ysiz; ///< j2k height of the reference grid (Ysiz) + uint32_t j2k_x0siz; ///< j2k horizontal offset from the origin of the reference grid to the left side of the image (X0siz) + uint32_t j2k_y0siz; ///< j2k vertical offset from the origin of the reference grid to the left side of the image (Y0siz) + uint32_t j2k_xtsiz; ///< j2k width of one reference tile with respect to the reference grid (XTsiz) + uint32_t j2k_ytsiz; ///< j2k height of one reference tile with respect to the reference grid (YTsiz) + uint32_t j2k_xt0siz; ///< j2k horizontal offset from the origin of the reference grid to the left side of the first tile (XT0siz) + uint32_t j2k_yt0siz; ///< j2k vertical offset from the origin of the reference grid to the left side of the first tile (YT0siz) + uint8_t j2k_comp_desc[12]; ///< j2k components descriptor (Ssiz(i), XRsiz(i), YRsiz(i)) } 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}}, /* Rsiz: 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}}, /* Xsiz: Width of the reference grid */ + { 0x8403, {0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x03,0x00,0x00,0x00}}, /* Ysiz: Height of the reference grid */ + { 0x8404, {0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x04,0x00,0x00,0x00}}, /* X0siz: 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}}, /* Y0siz: 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}}, /* XTsiz: 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}}, /* YTsiz: 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}}, /* XT0siz: 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}}, /* YT0siz: 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}}, /* 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. */ }; #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) { @@ -1365,6 +1410,66 @@ 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 (rsiz) */ + mxf_write_local_tag(s, 2, 0x8401); + avio_wb16(pb, sc->j2k_rsiz); + /* Width of the JPEG2000 reference grid (Xsiz) */ + mxf_write_local_tag(s, 4, 0x8402); + avio_wb32(pb, st->codecpar->width); + /* Height of the JPEG2000 reference grid (Ysiz) */ + 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 (X0siz) */ + 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 (Y0siz) */ + mxf_write_local_tag(s, 4, 0x8405); + avio_wb32(pb, sc->j2k_y0siz); + /* Width of one reference tile with respect to the reference grid (XTsiz) */ + mxf_write_local_tag(s, 4, 0x8406); + avio_wb32(pb, sc->j2k_xtsiz); + /* Height of one reference tile with respect to the reference grid (YTsiz) */ + 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 (XT0siz) */ + 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 (YT0siz) */ + mxf_write_local_tag(s, 4, 0x8409); + avio_wb32(pb, sc->j2k_yt0siz); + /* Image components number (Csiz) */ + 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 +1478,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 +2221,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); + Jpeg2000DecoderContext jpeg2000ctx; + AVCodecContext avctx; + GetByteContext *g = &(jpeg2000ctx.g); + uint32_t j2k_ncomponents; + int comp; + + if (mxf->header_written) + return 1; + + avctx.max_pixels = INT_MAX; + jpeg2000ctx.reduction_factor = 0; + jpeg2000ctx.avctx = &avctx; + 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, "Invalid J2K codestream: SOC marker not present.\n"); + return AVERROR(EINVAL); + } + + jpeg2000_read_main_headers(&jpeg2000ctx); + sc->j2k_rsiz = jpeg2000ctx.avctx->profile; // Rsiz + sc->j2k_xsiz = jpeg2000ctx.width; // Xsiz + sc->j2k_ysiz = jpeg2000ctx.height; // Ysiz + sc->j2k_x0siz = jpeg2000ctx.image_offset_x; // X0siz + sc->j2k_y0siz = jpeg2000ctx.image_offset_y; // Y0siz + sc->j2k_xtsiz = jpeg2000ctx.tile_width; // XTsiz + sc->j2k_ytsiz = jpeg2000ctx.tile_height; // YTsiz + sc->j2k_xt0siz = jpeg2000ctx.tile_offset_x; // XT0siz + sc->j2k_yt0siz = jpeg2000ctx.tile_offset_y; // YT0siz + j2k_ncomponents = jpeg2000ctx.ncomponents; // Csiz + if (j2k_ncomponents != component_count) { + av_log(s, AV_LOG_ERROR, "Incoherence about components image number.\n"); + return AVERROR(EINVAL); + } + for (comp = 0; comp < j2k_ncomponents; comp++) { + sc->j2k_comp_desc[comp*j2k_ncomponents] = (jpeg2000ctx.sgnd[comp]<<7)+jpeg2000ctx.cbps[comp]-1; // Ssiz(i) + sc->j2k_comp_desc[comp*j2k_ncomponents+1] = jpeg2000ctx.cdx[comp]; // XRsiz(i) + sc->j2k_comp_desc[comp*j2k_ncomponents+2] = jpeg2000ctx.cdy[comp]; // YRsiz(i)) + } + + sc->frame_size = pkt->size; + + return 1; +} + static const struct { const UID container_ul; const UID codec_ul; @@ -2958,6 +3118,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 [-- Attachment #3: 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-06-01 15:19 ` Cédric Le Barz @ 2023-06-04 18:24 ` Tomas Härdin 2023-09-22 9:26 ` Cédric Le Barz 0 siblings, 1 reply; 16+ messages in thread From: Tomas Härdin @ 2023-06-04 18:24 UTC (permalink / raw) To: FFmpeg development discussions and patches tor 2023-06-01 klockan 17:19 +0200 skrev Cédric Le Barz: > Attach to this mail, is my new patch for adding jpeg2000 sub- > descriptor > in MXF file taking into account remarks from FFmpeg community > (remarks > from Pierre-Anthony above as well as this from Tomas), i.e. : > > 1 - When there is a mismatch in components number, this is now > process > as an error. > > 2 - When defining and using the J2K descriptor items, I now refer to > the > symbol name from the SMPTE registers (X0siz, XT0siz...) > > 3 - As suggested, I make use of jpeg2000_read_main_headers() in > libavcodec. But, I let the parsing function in mxfenc.c file as all > other parsing functions are in this file (mxf_parse_mpeg2_frame, > mxf_parse_h264_frame...). The use of jpeg2000_read_main_headers() in > mxfenc implies some minor modifications in jpeg2000 files : > > * rename of Jpeg2000Tile structure to J2kTile in j2kenc.c (to avoid > redefinition) > > * move some structure declarations from jpeg2000dec.c to jpeg2000.h > > * make jpeg2000_read_main_headers() function "public" For this you need to prefix the name with ff_ and bump libavcodec's minor version number > +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); > + Jpeg2000DecoderContext jpeg2000ctx; This makes sizeof(Jpeg2000DecoderContext) part of the public API which is a big no-no. Consider making the fields part of a different smaller struct instead that is also included in Jpeg2000DecoderContext. The safest option is to have a function that allocates that struct. The reason for this is because we might want to read other things from the headers at a later date. Another possibility is to pass a bunch of pointers to ints that the parsed values get written to. If at a later date we need to parse more fields then we can introduce ff_jpeg2000_read_main_headers_2() and so on. The latter seems easier API stability wise, if a bit tedious with the number of function arguments. /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-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-06-04 18:24 ` Tomas Härdin @ 2023-09-22 9:26 ` Cédric Le Barz 0 siblings, 0 replies; 16+ messages in thread From: Cédric Le Barz @ 2023-09-22 9:26 UTC (permalink / raw) To: FFmpeg development discussions and patches Le 04/06/2023 à 20:24, Tomas Härdin a écrit : > tor 2023-06-01 klockan 17:19 +0200 skrev Cédric Le Barz: >> Attach to this mail, is my new patch for adding jpeg2000 sub- >> descriptor >> in MXF file taking into account remarks from FFmpeg community >> (remarks >> from Pierre-Anthony above as well as this from Tomas), i.e. : >> >> 1 - When there is a mismatch in components number, this is now >> process >> as an error. >> >> 2 - When defining and using the J2K descriptor items, I now refer to >> the >> symbol name from the SMPTE registers (X0siz, XT0siz...) >> >> 3 - As suggested, I make use of jpeg2000_read_main_headers() in >> libavcodec. But, I let the parsing function in mxfenc.c file as all >> other parsing functions are in this file (mxf_parse_mpeg2_frame, >> mxf_parse_h264_frame...). The use of jpeg2000_read_main_headers() in >> mxfenc implies some minor modifications in jpeg2000 files : >> >> * rename of Jpeg2000Tile structure to J2kTile in j2kenc.c (to avoid >> redefinition) >> >> * move some structure declarations from jpeg2000dec.c to jpeg2000.h >> >> * make jpeg2000_read_main_headers() function "public" > For this you need to prefix the name with ff_ and bump libavcodec's > minor version number > >> +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); >> + Jpeg2000DecoderContext jpeg2000ctx; > This makes sizeof(Jpeg2000DecoderContext) part of the public API which > is a big no-no. Consider making the fields part of a different smaller > struct instead that is also included in Jpeg2000DecoderContext. The > safest option is to have a function that allocates that struct. The > reason for this is because we might want to read other things from the > headers at a later date. Another possibility is to pass a bunch of > pointers to ints that the parsed values get written to. If at a later > date we need to parse more fields then we can introduce > ff_jpeg2000_read_main_headers_2() and so on. The latter seems easier > API stability wise, if a bit tedious with the number of function > arguments. > > /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-request@ffmpeg.org with subject "unsubscribe". Hi, I'm facing a problem to get the jpeg2000 information I need to build the mxf file. All the functions to extract jpeg2000 information exist : they are located in libavcodec side and used Jpeg2000DecoderContext, which is not obviously public and therefore unknown from libavformat side. Is there a way to get a pointer on the Jpeg2000DecoderContext (at least a void*) from libavcodec side ? Thanks for your help. Cédric _______________________________________________ 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-04-03 8:08 ` Cédric Le Barz 2023-04-03 15:14 ` Michael Niedermayer @ 2023-04-05 12:39 ` Tomas Härdin 1 sibling, 0 replies; 16+ messages in thread From: Tomas Härdin @ 2023-04-05 12:39 UTC (permalink / raw) To: FFmpeg development discussions and patches > + { > + char _layout[16] = { 'Y' , '\n', 'U' , '\n', 'V' , '\n', > 'F' , 0x02, > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00 }; > + avio_write(pb, _layout , 16); > + } What about RGB(A)? > @@ -3311,3 +3382,4 @@ const FFOutputFormat ff_mxf_opatom_muxer = { > .interleave_packet = mxf_interleave, > .p.priv_class = &mxf_opatom_muxer_class, > }; > + Stray newline /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-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA 2023-03-29 20:54 [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA Cédric Le Barz 2023-03-31 21:47 ` Michael Niedermayer @ 2023-04-23 1:07 ` Pierre-Anthony Lemieux 1 sibling, 0 replies; 16+ messages in thread From: Pierre-Anthony Lemieux @ 2023-04-23 1:07 UTC (permalink / raw) To: FFmpeg development discussions and patches On Wed, Mar 29, 2023 at 1:54 PM Cédric Le Barz <clebarz@ektacom.com> wrote: > > Add jpeg2000 subdescriptor in MXF file. > > Signed-off-by: Cedric Le Barz <clebarz@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@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] 16+ messages in thread
end of thread, other threads:[~2023-09-22 9:26 UTC | newest] Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-03-29 20:54 [FFmpeg-devel] [PATCH] MXF - Add jpeg2000 subdescriptor - Sponsored by INA Cédric Le Barz 2023-03-31 21:47 ` Michael Niedermayer 2023-04-03 8:08 ` Cédric Le Barz 2023-04-03 15:14 ` Michael Niedermayer 2023-04-05 13:05 ` Cédric Le Barz 2023-04-05 13:53 ` Tomas Härdin 2023-04-25 14:33 ` Cédric Le Barz 2023-04-27 12:45 ` Tomas Härdin 2023-05-02 15:43 ` Cédric Le Barz 2023-05-09 9:49 ` Tomas Härdin 2023-05-09 14:28 ` Pierre-Anthony Lemieux 2023-06-01 15:19 ` Cédric Le Barz 2023-06-04 18:24 ` Tomas Härdin 2023-09-22 9:26 ` Cédric Le Barz 2023-04-05 12:39 ` Tomas Härdin 2023-04-23 1:07 ` 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