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]
