This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 536475ea058245e71f5c2e7f3d5c39b0cad465e5
Author:     jess <[email protected]>
AuthorDate: Mon Jun 16 10:54:30 2025 +0900
Commit:     James Almer <[email protected]>
CommitDate: Sat Dec 13 19:03:43 2025 -0300

    avformat/mpegts: add support for JPEG-XS streams
    
    Co-Authored-by: James Almer <[email protected]>
    Signed-off-by: James Almer <[email protected]>
---
 libavformat/mpegts.c    | 107 +++++++++++++++++++++++++++++++++++++++++++++++-
 libavformat/mpegts.h    |   7 +++-
 libavformat/mpegtsenc.c |   2 +-
 3 files changed, 113 insertions(+), 3 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 33f2914104..fb1dcd11be 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -815,6 +815,7 @@ static const StreamType ISO_types[] = {
     { STREAM_TYPE_VIDEO_MVC,      AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264       },
     { STREAM_TYPE_VIDEO_JPEG2000, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000   },
     { STREAM_TYPE_VIDEO_HEVC,     AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC       },
+    { STREAM_TYPE_VIDEO_JPEGXS,   AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEGXS     },
     { STREAM_TYPE_VIDEO_VVC,      AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VVC        },
     { STREAM_TYPE_VIDEO_CAVS,     AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS       },
     { STREAM_TYPE_VIDEO_DIRAC,    AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC      },
@@ -1028,6 +1029,16 @@ static int new_pes_packet(PESContext *pes, AVPacket *pkt)
         av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n");
         pes->flags |= AV_PKT_FLAG_CORRUPT;
     }
+
+    // JPEG-XS PES payload
+    if (pes->stream_id == 0xbd && pes->stream_type == 0x32 &&
+        pkt->size >= 8 && memcmp(pkt->data + 4, "jxes", 4) == 0)
+    {
+        uint32_t header_size = AV_RB32(pkt->data);
+        pkt->data += header_size;
+        pkt->size -= header_size;
+    }
+
     memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
 
     // Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID
@@ -1816,6 +1827,92 @@ static const uint8_t opus_channel_map[8][8] = {
     { 0,6,1,2,3,4,5,7 },
 };
 
+static int parse_mpeg2_extension_descriptor(AVFormatContext *fc, AVStream *st,
+                                            const uint8_t **pp, const uint8_t 
*desc_end)
+{
+    int ext_tag = get8(pp, desc_end);
+
+    switch (ext_tag) {
+    case JXS_VIDEO_DESCRIPTOR: /* JPEG-XS video descriptor*/
+        {
+            int horizontal_size, vertical_size, schar;
+            int colour_primaries, transfer_characteristics, 
matrix_coefficients, video_full_range_flag;
+            int descriptor_version, interlace_mode, n_fields;
+            unsigned frat;
+
+            if (desc_end - *pp < 29)
+                return AVERROR_INVALIDDATA;
+
+            descriptor_version = get8(pp, desc_end);
+            if (descriptor_version) {
+                av_log(fc, AV_LOG_WARNING, "Unsupported JPEG-XS descriptor 
version (%d != 0)", descriptor_version);
+                return AVERROR_INVALIDDATA;
+            }
+
+            horizontal_size = get16(pp, desc_end);
+            vertical_size = get16(pp, desc_end);
+            *pp += 4; /* brat */
+            frat = bytestream_get_be32(pp);
+            schar = get16(pp, desc_end);
+            *pp += 2; /* Ppih */
+            *pp += 2; /* Plev */
+            *pp += 4; /* max_buffer_size */
+            *pp += 1; /* buffer_model_type */
+            colour_primaries = get8(pp, desc_end);
+            transfer_characteristics = get8(pp, desc_end);
+            matrix_coefficients = get8(pp, desc_end);
+            video_full_range_flag = (get8(pp, desc_end) & 0x80) == 0x80 ? 1 : 
0;
+
+            interlace_mode = (frat >> 30) & 0x3;
+            if (interlace_mode == 3) {
+                av_log(fc, AV_LOG_WARNING, "Unknown JPEG XS interlace mode 3");
+                return AVERROR_INVALIDDATA;
+            }
+
+            st->codecpar->field_order = interlace_mode == 0 ? 
AV_FIELD_PROGRESSIVE
+                                                            : (interlace_mode 
== 1 ? AV_FIELD_TT : AV_FIELD_BB);
+            n_fields = st->codecpar->field_order == AV_FIELD_PROGRESSIVE ? 1 : 
2;
+
+            st->codecpar->width  = horizontal_size;
+            st->codecpar->height = vertical_size * n_fields;
+
+            if (frat != 0) {
+                int framerate_num = (frat & 0x0000FFFFU);
+                int framerate_den = ((frat >> 24) & 0x0000003FU);
+
+                if (framerate_den == 2) {
+                    framerate_num *= 1000;
+                    framerate_den = 1001;
+                } else if (framerate_den != 1) {
+                    av_log(fc, AV_LOG_WARNING, "Unknown JPEG XS framerate 
denominator code %u", framerate_den);
+                    return AVERROR_INVALIDDATA;
+                }
+
+                st->codecpar->framerate.num = framerate_num;
+                st->codecpar->framerate.den = framerate_den;
+            }
+
+            switch (schar & 0xf) {
+            case 0: st->codecpar->format = AV_PIX_FMT_YUV422P10LE; break;
+            case 1: st->codecpar->format = AV_PIX_FMT_YUV444P10LE; break;
+            default:
+                av_log(fc, AV_LOG_WARNING, "Unknown JPEG XS sampling format");
+                break;
+            }
+
+            st->codecpar->color_range = video_full_range_flag ? 
AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
+            st->codecpar->color_primaries = colour_primaries;
+            st->codecpar->color_trc = transfer_characteristics;
+            st->codecpar->color_space = matrix_coefficients;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return 0;
+}
+
 int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int 
stream_type,
                               const uint8_t **pp, const uint8_t *desc_list_end,
                               Mp4Descr *mp4_descr, int mp4_descr_count, int 
pid,
@@ -2043,7 +2140,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, 
AVStream *st, int stream_type
                 mpegts_find_stream_type(st, st->codecpar->codec_tag, 
METADATA_types);
         }
         break;
-    case EXTENSION_DESCRIPTOR: /* DVB extension descriptor */
+    case DVB_EXTENSION_DESCRIPTOR: /* DVB extension descriptor */
         ext_desc_tag = get8(pp, desc_end);
         if (ext_desc_tag < 0)
             return AVERROR_INVALIDDATA;
@@ -2248,6 +2345,14 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, 
AVStream *st, int stream_type
                    dovi->dv_md_compression);
         }
         break;
+    case EXTENSION_DESCRIPTOR: /* descriptor extension */
+        {
+            int ret = parse_mpeg2_extension_descriptor(fc, st, pp, desc_end);
+
+            if (ret < 0)
+                return ret;
+        }
+        break;
     default:
         break;
     }
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 2bc53447d0..223962d18e 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -144,6 +144,7 @@
 #define STREAM_TYPE_VIDEO_MVC       0x20
 #define STREAM_TYPE_VIDEO_JPEG2000  0x21
 #define STREAM_TYPE_VIDEO_HEVC      0x24
+#define STREAM_TYPE_VIDEO_JPEGXS    0x32
 #define STREAM_TYPE_VIDEO_VVC       0x33
 #define STREAM_TYPE_VIDEO_CAVS      0x42
 #define STREAM_TYPE_VIDEO_AVS2      0xd2
@@ -202,8 +203,12 @@ 
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/
 #define FMC_DESCRIPTOR               0x1f
 #define METADATA_DESCRIPTOR          0x26
 #define METADATA_STD_DESCRIPTOR      0x27
+#define EXTENSION_DESCRIPTOR         0x3f
 /* descriptor_tag values [0x40, 0xff] are User Private */
 
+/* ISO/IEC 13818-1 Table 2-109 */
+#define JXS_VIDEO_DESCRIPTOR         0x14 /* JPEG-XS descriptor */
+
 /* DVB descriptor tag values [0x40, 0x7F] from
    ETSI EN 300 468 Table 12: Possible locations of descriptors */
 #define NETWORK_NAME_DESCRIPTOR      0x40
@@ -215,7 +220,7 @@ 
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/
 #define AC3_DESCRIPTOR               0x6a /* AC-3_descriptor */
 #define ENHANCED_AC3_DESCRIPTOR      0x7a /* enhanced_AC-3_descriptor */
 #define DTS_DESCRIPTOR               0x7b
-#define EXTENSION_DESCRIPTOR         0x7f
+#define DVB_EXTENSION_DESCRIPTOR     0x7f
 
 /* DVB descriptor_tag_extension values from
    ETSI EN 300 468 Table 109: Possible locations of extended descriptors */
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 6935b71cfe..ea7c6065a0 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -618,7 +618,7 @@ static int mpegts_write_pmt(AVFormatContext *s, 
MpegTSService *service)
 
                 put_registration_descriptor(&q, MKTAG('O', 'p', 'u', 's'));
 
-                *q++ = EXTENSION_DESCRIPTOR; /* DVB extension descriptor */
+                *q++ = DVB_EXTENSION_DESCRIPTOR;
                 *q++ = 2;
                 *q++ = 0x80;
 

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to