From: pierrelefevre via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: pierrelefevre <code@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] avformat/mpegts: Passthrough SCTE 35 (PR #20342) Message-ID: <175620663902.34.10087014612919019866@5a0384606a8e> (raw) PR #20342 opened by pierrelefevre URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20342 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20342.patch Current behavior breaks SCTE 35 streams by wrapping the data in a PES packet. This MR lets SCTE 35 pass through cleanly without modification. >From da29faa314e3abc5f325a0988ac1424d8e4a0746 Mon Sep 17 00:00:00 2001 From: Pierre Le Fevre <hello@pierrelf.com> Date: Wed, 11 Jun 2025 15:25:13 +0200 Subject: [PATCH] avformat/mpegts: Passthrough SCTE 35 Current behavior breaks SCTE 35 by wrapping it in a PES packet, this adds the logic for the SCTE 35 messages to be passed through cleanly. Signed-off-by: Pierre Le Fevre <hello@pierrelf.com> --- libavformat/mpegtsenc.c | 27 +++++++++++++++++++++++++++ libavformat/mux.c | 6 ++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 6935b71cfe..ba28e17696 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -84,6 +84,7 @@ typedef struct MpegTSWrite { MpegTSSection pat; /* MPEG-2 PAT table */ MpegTSSection sdt; /* MPEG-2 SDT table context */ MpegTSSection nit; /* MPEG-2 NIT table context */ + MpegTSSection scte35; MpegTSService **services; AVPacket *pkt; int64_t sdt_period; /* SDT period in PCR time base */ @@ -443,6 +444,9 @@ static int get_dvb_stream_type(AVFormatContext *s, AVStream *st) stream_type = STREAM_TYPE_PRIVATE_DATA; } break; + case AV_CODEC_ID_SCTE_35: + stream_type = STREAM_TYPE_SCTE_DATA_SCTE_35; + break; default: av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning, "Stream %d, codec %s, is muxed as a private data stream " @@ -530,6 +534,13 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *q++ = 0xfc; // private_data_byte } + for (i = 0; i < s->nb_streams; i++) { + if(s->streams[i]->codecpar->codec_id==AV_CODEC_ID_SCTE_35) { + put_registration_descriptor(&q, MKTAG('C', 'U', 'E', 'I')); + break; + } + } + val = 0xf000 | (q - program_info_length_ptr - 2); program_info_length_ptr[0] = val >> 8; program_info_length_ptr[1] = val; @@ -1160,6 +1171,11 @@ static int mpegts_init(AVFormatContext *s) ts->nit.write_packet = section_write_packet; ts->nit.opaque = s; + ts->scte35.cc = 15; + ts->scte35.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; + ts->scte35.write_packet = section_write_packet; + ts->scte35.opaque = s; + ts->pkt = ffformatcontext(s)->pkt; /* assign pids to each stream */ @@ -2195,6 +2211,17 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY, stream_id); return 0; + } else if (st->codecpar->codec_id == AV_CODEC_ID_SCTE_35) { + uint8_t q[1024]; + unsigned int len; + + len = pkt->size; + memcpy(q, pkt->data, len); + + ts->scte35.pid = ts_st->pid; + + mpegts_write_section(&ts->scte35, q, len); + return 0; } if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size || diff --git a/libavformat/mux.c b/libavformat/mux.c index db3b6c2bfe..411c9674df 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -325,7 +325,8 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) } if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT && - par->codec_id != AV_CODEC_ID_SMPTE_2038) + par->codec_id != AV_CODEC_ID_SMPTE_2038 && + par->codec_id != AV_CODEC_ID_SCTE_35) fci->nb_interleaved_streams++; } fci->interleave_packet = of->interleave_packet; @@ -959,7 +960,8 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt, } else if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT && par->codec_id != AV_CODEC_ID_VP8 && par->codec_id != AV_CODEC_ID_VP9 && - par->codec_id != AV_CODEC_ID_SMPTE_2038) { + par->codec_id != AV_CODEC_ID_SMPTE_2038 && + par->codec_id != AV_CODEC_ID_SCTE_35) { ++noninterleaved_count; } } -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
reply other threads:[~2025-08-26 11:12 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=175620663902.34.10087014612919019866@5a0384606a8e \ --to=ffmpeg-devel@ffmpeg.org \ --cc=code@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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