Message ID | 2a3fb2cb-1f37-a3f5-950a-8e6c943f3fd4@m1stereo.tv |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] avformat/mpegtsenc: Implement muxing SCTE-35 and EPG packets | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
andriy/make_ppc | success | Make finished |
andriy/make_fate_ppc | success | Make fate finished |
On Mon, 8 Nov 2021 at 06:35, Maksym Veremeyenko <verem@m1stereo.tv> wrote: > Hi, > > Attached patch implement muxing SCTE-35 and EPG packets into mpegts stream. > SCTE Markers need timestamping, no? Kieran
On 08.11.2021 16:41, Kieran Kunhya wrote: > On Mon, 8 Nov 2021 at 06:35, Maksym Veremeyenko <verem@m1stereo.tv> wrote: > >> Hi, >> >> Attached patch implement muxing SCTE-35 and EPG packets into mpegts stream. >> > > SCTE Markers need timestamping, no? > SCTE markers has no timestamping, during reading at mpegts.c it timestamps recovered from PCR.
On Mon, 8 Nov 2021 at 15:17, Maksym Veremeyenko <verem@m1stereo.tv> wrote: > On 08.11.2021 16:41, Kieran Kunhya wrote: > > On Mon, 8 Nov 2021 at 06:35, Maksym Veremeyenko <verem@m1stereo.tv> > wrote: > > > >> Hi, > >> > >> Attached patch implement muxing SCTE-35 and EPG packets into mpegts > stream. > >> > > > > SCTE Markers need timestamping, no? > > > > SCTE markers has no timestamping, during reading at mpegts.c it > timestamps recovered from PCR. > The positioning of the packet relative to the PCR matters. Also splice_time() is relative to the new PCR and timestamps which I don't think the mux here can guarantee? Kieran
On 08.11.2021 17:31, Kieran Kunhya wrote: [...] > The positioning of the packet relative to the PCR matters. Also > splice_time() is relative to the new PCR and timestamps which I don't think > the mux here can guarantee? i could be wrong, but time_signal() carry splice_time() what carry pts_time that /indicates time in terms of ticks of the program’s 90 kHz clock/, it does not relates to PCR but relates to PTS of video stream.
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index e3fba54..1fe3f55 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -429,6 +429,12 @@ 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 = 0x86; + break; + case AV_CODEC_ID_EPG: + stream_type = 0; + 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 " @@ -514,6 +520,16 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *q++ = 0xfc; // private_data_byte } + /* put scte-35 registration tag */ + for (i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + + if (st->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; @@ -547,6 +563,9 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) stream_type = ts->m2ts_mode ? get_m2ts_stream_type(s, st) : get_dvb_stream_type(s, st); + if (!stream_type) + continue; + *q++ = stream_type; put16(&q, 0xe000 | ts_st->pid); desc_length_ptr = q; @@ -2099,6 +2118,34 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) ts_st->dvb_ac3_desc = dvb_ac3_desc; } av_free(hdr); + } else if (st->codecpar->codec_id == AV_CODEC_ID_SCTE_35) { + MpegTSSection sec; + + sec.pid = ts_st->pid; + sec.cc = ts_st->payload_size; + sec.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; + sec.write_packet = section_write_packet; + sec.opaque = s; + + mpegts_write_section(&sec, pkt->data, pkt->size); + + ts_st->payload_size = sec.cc; + + return 0; + } else if (st->codecpar->codec_id == AV_CODEC_ID_EPG) { + MpegTSSection sec; + + sec.pid = EIT_PID; + sec.cc = ts_st->payload_size; + sec.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; + sec.write_packet = section_write_packet; + sec.opaque = s; + + mpegts_write_section(&sec, pkt->data, pkt->size); + + ts_st->payload_size = sec.cc; + + return 0; } if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size ||