Re: [FFmpeg-devel] [PATCH 3/4] V13 - SCTE-35 support in hlsenc
On Sat, Oct 15, 2016 at 1:44 AM, Anssi Hannula wrote: > > Function pointers are not useful here as they always point to the same > functions. Function pointer are kept there so that scte_35.c function are not exposed to users using ffmpeg library. > > Also, the members of this "interface" struct seem to be mostly scte_35.c > internal stuff that shouldn't be in a header. The scte35_interface keeps the context of scte35 and we need to make an instance of it in hlsenc. All other things corrected (I think) - will send a patch soon. Thanks! Carlos ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V14 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 47 +-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..932ffc1 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -725,6 +725,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +878,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1590,6 +1603,27 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, av_free(mp4_descr[i].dec_config_descr); } +static void scte_data_cb(MpegTSFilter *filter, const uint8_t *section, +int section_len) +{ +AVProgram *prg = NULL; +MpegTSContext *ts = filter->u.section_filter.opaque; + +int idx = ff_find_stream_index(ts->stream, filter->pid); +new_data_packet(section, section_len, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, NULL, idx); +if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { +MpegTSFilter *f = ts->pids[prg->pcr_pid]; +if (f) +ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; + +} + static const uint8_t opus_coupled_stream_cnt[9] = { 1, 0, 1, 1, 2, 2, 2, 3, 3 }; @@ -1868,6 +1902,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type return 0; } +static int is_pes_stream(int stream_type, uint32_t prog_reg_desc) +{ +return !(stream_type == 0x13 || + (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) ); +} + static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; @@ -1975,7 +2015,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; -} else if (stream_type != 0x13) { +} else if (is_pes_stream(stream_type, prog_reg_desc)) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); @@ -1995,6 +2035,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len goto out; st->id = pid; st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_section_filter(ts, pid, scte_data_cb, ts, 1); +} } } @@ -2317,7 +2361,6 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - } else { int ret; // Note: The position here points actually behind the current packet. -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] V14 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 01e3237..8d99154 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -391,12 +391,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] V14 - SCTE-35 support
- Addresses all things mentioned by Anssi Hannula about HLS Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 112 +++--- libavformat/mpegts.c| 47 - libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 753 insertions(+), 28 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V14 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ 2 files changed, 7 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index d72ee07..e68dd93 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -631,6 +631,7 @@ enum AVCodecID { AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35,///< Contain timestamp estimated through PCR of program stream. AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V14 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 104 -- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 697 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9ca2df7..01e3237 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte35_event *event; +enum scte35_event_state event_state; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -108,6 +113,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -241,6 +248,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -360,8 +369,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); const char *filename; @@ -384,9 +393,20 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) +hls->adv_count++; +else +hls->adv_count = 0; +en->event_state = hls->scte_iface->event_state; +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -460,7 +480,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -590,9 +610,19 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && en->event) { +char *str; +char fname[1024] = ""; +if (hls->baseurl) +strncat(fname, hls->baseurl, sizeof(fname)-1); +strncat(fname, en->filename, sizeof(fname)-strlen(fname)-1); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, fname, en->event_state, -1, en->start_pts); +avio_printf(out, "%s", str); +} else { +if (hls->baseurl) +avio_printf(out, "%s", hls->baseurl); +avio_print
Re: [FFmpeg-devel] [PATCH 3/4] V13 - SCTE-35 support in hlsenc
On Sun, Oct 16, 2016 at 10:59 AM, Carlos Fernandez Sanz wrote: > > All other things corrected (I think) - will send a patch soon. Thanks! I submitted V14 yesterday - can you take a look and comment and/or merge? Thanks ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/4] V14 - Adding SCTE-35 CUI codec
On Fri, Oct 21, 2016 at 5:17 PM, Kieran Kunhya wrote: > > So all the objections to this patchset are now irrelevant are they? Just curious - what are the objections to this patchset and where were they raised? I don't think there's _anything_ posted in this mailing list that hasn't been corrected or replied to. That's why we're at V14 already. If there's other places I should have been keeping track of but didn't, I apologize. Carlos ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/4] V14 - Adding SCTE-35 CUI codec
On Sat, Oct 22, 2016 at 4:15 AM, Kieran Kunhya wrote: > > Getting patches merged by sheer attrition is a shameful way of "running" an > open source project. I think ignoring follow-up questions from the patch submitter, like you are doing with mine, it's plain rude. Basically your position is "SCTE-35 doesn't fit into ffmpeg's model therefore it cannot be supported, ever, and the industry professionals that want SCTE-35 just need to find a different program". Did I sum it up correctly? Really, if there's a problem with my implementation -totally possible- I'm more than happy to discuss and iterate. And of course I won't take offense if you send a patch over it or a total rewrite that is better than mine. But whining about the fact that my patch has been -partially- merged even though you wanted to veto it "just because" it's childish. Carlos ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/4] V14 - SCTE-35 support in hlsenc
Hi, Just a ping in case this can be revised and/or applied soonish - thanks. CC'ing Carl Eugen and Thilo since I could discuss this a bit in person at the GSoC summit. Thanks both for your time by the way. Carlos On Tue, Oct 18, 2016 at 5:36 PM, Carlos Fernandez Sanz wrote: > From: Carlos Fernandez > > Signed-off-by: Carlos Fernandez > --- > libavformat/Makefile | 2 +- > libavformat/hlsenc.c | 104 -- > libavformat/scte_35.c | 527 > ++ > libavformat/scte_35.h | 86 > 4 files changed, 697 insertions(+), 22 deletions(-) > create mode 100644 libavformat/scte_35.c > create mode 100644 libavformat/scte_35.h > > diff --git a/libavformat/Makefile b/libavformat/Makefile > index 5d827d31..9218606 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o > OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o > OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o > OBJS-$(CONFIG_HLS_DEMUXER) += hls.o > -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o > +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o > OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o > OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o > OBJS-$(CONFIG_ICO_MUXER) += icoenc.o > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index 9ca2df7..01e3237 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -38,6 +38,7 @@ > #include "avio_internal.h" > #include "internal.h" > #include "os_support.h" > +#include "scte_35.h" > > #define KEYSIZE 16 > #define LINE_BUFFER_SIZE 1024 > @@ -48,6 +49,10 @@ typedef struct HLSSegment { > double duration; /* in seconds */ > int64_t pos; > int64_t size; > +struct scte35_event *event; > +enum scte35_event_state event_state; > +int adv_count; > +int64_t start_pts; > > char key_uri[LINE_BUFFER_SIZE + 1]; > char iv_string[KEYSIZE*2 + 1]; > @@ -108,6 +113,8 @@ typedef struct HLSContext { > int nb_entries; > int discontinuity_set; > > +int adv_count; > +struct scte35_interface *scte_iface; > HLSSegment *segments; > HLSSegment *last_segment; > HLSSegment *old_segments; > @@ -241,6 +248,8 @@ static int hls_delete_old_segments(HLSContext *hls) { > av_freep(&path); > previous_segment = segment; > segment = previous_segment->next; > +if (hls->scte_iface) > +hls->scte_iface->unref_scte35_event(&previous_segment->event); > av_free(previous_segment); > } > > @@ -360,8 +369,8 @@ static int hls_mux_init(AVFormatContext *s) > } > > /* Create a new segment and append it to the segment list */ > -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, > double duration, > - int64_t pos, int64_t size) > +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, > double duration, int64_t pos, > + int64_t start_pts, struct scte35_event *event, > int64_t size) > { > HLSSegment *en = av_malloc(sizeof(*en)); > const char *filename; > @@ -384,9 +393,20 @@ static int hls_append_segment(struct AVFormatContext *s, > HLSContext *hls, double > > en->duration = duration; > en->pos = pos; > +en->event= event; > en->size = size; > +en->start_pts = start_pts; > en->next = NULL; > > +if (hls->scte_iface) { > +if (hls->scte_iface->event_state == EVENT_OUT_CONT) > +hls->adv_count++; > +else > +hls->adv_count = 0; > +en->event_state = hls->scte_iface->event_state; > +} > + > + > if (hls->key_info_file) { > av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); > av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); > @@ -460,7 +480,7 @@ static int parse_playlist(AVFormatContext *s, const char > *url) > new_start_pos = avio_tell(hls->avf->pb); > hls->size = new_start_pos - hls->start_pos; > av_strlcpy(hls->avf->filename, line, sizeof(line)); > -ret = hls_append_segment(s, hls, hls->duration, > hls->start_pos, hls->size); > +ret = hls_append_segment(s, hls, hls->duration, > hls->start_pos, 0, NULL, hls->size); >
Re: [FFmpeg-devel] TR-03 implementation
On Sat, Nov 12, 2016 at 8:17 PM, Ali KIZIL wrote: > If someone wants to try, he can give a try, release a patch, it can be > discussed in a discussion level. I really find saying such comments like " > We don't need more broadcasting shit in ffmpeg." and "and it is why > FFmpeg is full of broken things and has a bad name in the professional > world." annoying. Frankly speaking, as my own, I start to think maybe some > people try to give intentional directions to FFmpeg. > And rumor has it, want to the broadcasting industry to other products. One of the reasons apparently for not merging the SCTE-35 patch; better never include that in ffmpeg and have the professional use and pay for other products even though an implementation that doesn't break anything at that has been revised 14 times has been posted here. Reason not to merge? None, that just it "doesn't belong to FFmpeg". And trying to merge it is not mature. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] SCTE extraction from mpegts
From: Carlos Signed-off-by: carlos --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavformat/mpegts.c| 46 -- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ca8dba8..df8e2f3 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -628,6 +628,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index dea17c9..5c00be0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2950,6 +2950,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..99631b1 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -705,6 +711,7 @@ static const StreamType ISO_types[] = { { 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 }, { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1}, { 0 }, @@ -872,6 +879,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1989,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, ISO_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,15 +2344,20 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - -} else { +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; +} else if (tss->type == MPEGTS_PES) { int ret; // Note: The position here points actually behind the current packet. -if (tss->type == MPEGTS_PES) { -if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, +if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, pos - ts->raw_packet_size)) < 0) -return ret; -} +return ret; } return 0; @@ -2730,6 +2762,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___
[FFmpeg-devel] [PATCH 0/2] SCTE-35 support
These two patches add support for SCTE-35. First, parse it correct from MPEG, then segment appropiately. Carlos (1): SCTE extraction from mpegts carlos (1): SCTE-35 support in hlsenc libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 1 + libavformat/hlsenc.c| 179 +++--- libavformat/mpegts.c| 46 - libavformat/scte_35.c | 489 libavformat/scte_35.h | 76 7 files changed, 727 insertions(+), 71 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] SCTE-35 support in hlsenc
From: carlos Signed-off-by: carlos --- libavformat/Makefile | 1 + libavformat/hlsenc.c | 179 +++--- libavformat/scte_35.c | 489 ++ libavformat/scte_35.h | 76 4 files changed, 680 insertions(+), 65 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index c3f38b4..59f5046 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -21,6 +21,7 @@ OBJS = allformats.o \ qtpalette.o \ protocols.o \ riff.o \ + scte_35.o\ sdp.o\ url.o\ utils.o \ diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5dc518d..0b1052b 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,7 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -132,9 +140,10 @@ static int hls_delete_old_segments(HLSContext *hls) { HLSSegment *segment, *previous_segment = NULL; float playlist_duration = 0.0f; -int ret = 0, path_size, sub_path_size; -char *dirname = NULL, *p, *sub_path; -char *path = NULL; +int ret = 0; +size_t dir_size; +const char *dirname; +char *base, *path; segment = hls->segments; while (segment) { @@ -147,69 +156,55 @@ static int hls_delete_old_segments(HLSContext *hls) { playlist_duration -= segment->duration; previous_segment = segment; segment = previous_segment->next; -if (playlist_duration <= -previous_segment->duration) { +//if (playlist_duration <= -previous_segment->duration) { +if (playlist_duration <= 9) { previous_segment->next = NULL; break; } } -if (segment) { -if (hls->segment_filename) { -dirname = av_strdup(hls->segment_filename); -} else { -dirname = av_strdup(hls->avf->filename); -} -if (!dirname) { -ret = AVERROR(ENOMEM); -goto fail; -} -p = (char *)av_basename(dirname); -*p = '\0'; +if (!segment) +return ret; + +if (hls->segment_filename) { +dirname = hls->segment_filename; +} else { +dirname = hls->avf->filename; +} + +dir_size = av_basename(dirname) - dirname; +path = av_malloc(PATH_MAX); +if (!path) { +return (ret = AVERROR(ENOMEM)); } +(void)av_strlcpy(path, dirname, PATH_MAX); +base = &path[dir_size]; while (segment) { av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n", segment->filename); -path_size = strlen(dirname) + strlen(segment->filename) + 1; -path = av_malloc(path_size); -if (!path) { -ret = AVERROR(ENOMEM); -goto fail; -} -av_strlcpy(path, dirname, path_size); -av_strlcat(path, segment->filename, path_size); +av_strlcat(base, segment->filename, PATH_MAX); if (unlink(path) < 0) { av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n", path, strerror(errno)); } -if (segment->sub_filename[0] != '\0') { -sub_path_size = strlen(dirname) + strlen(segment->sub_filename) + 1; -sub_path = av_malloc(sub_path_size); -if (!sub_path) { -ret = AVERROR(ENOMEM); -goto fail; -} - -av_strlcpy(sub_path, dirname, sub_path_size); -av_strlcat(sub_path, segment->sub_filename, sub_path_size); -if (unlink(sub_path) < 0) { +if (hls->has_subtitle) { +av_strlcat(base, segment->sub_filename, PATH_MAX); +if (unlink(path) < 0) { av_log(hls, AV_LOG_ERROR, "failed to delete old
[FFmpeg-devel] [PATCH 0/2] v2 - SCTE-35 support
These two patches add support for SCTE-35. First, parse it correct from MPEG, then segment appropiately. All things reported about v1 addressed: - Removed commented out code - Spaces where there was a tab - Should build on mingw64 (removed probable cause of error) - Made it a hls muxer dependency instead of libavformat Carlos (1): SCTE extraction from mpegts carlos (1): SCTE-35 support in hlsenc libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 110 --- libavformat/mpegts.c| 46 - libavformat/scte_35.c | 482 libavformat/scte_35.h | 76 7 files changed, 693 insertions(+), 30 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] v2 SCTE extraction from mpegts
From: Carlos Signed-off-by: carlos --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavformat/mpegts.c| 46 -- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ca8dba8..df8e2f3 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -628,6 +628,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index dea17c9..5c00be0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2950,6 +2950,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..99631b1 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -705,6 +711,7 @@ static const StreamType ISO_types[] = { { 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 }, { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1}, { 0 }, @@ -872,6 +879,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1989,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, ISO_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,15 +2344,20 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - -} else { +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; +} else if (tss->type == MPEGTS_PES) { int ret; // Note: The position here points actually behind the current packet. -if (tss->type == MPEGTS_PES) { -if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, +if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, pos - ts->raw_packet_size)) < 0) -return ret; -} +return ret; } return 0; @@ -2730,6 +2762,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___
[FFmpeg-devel] [PATCH 2/2] v2 SCTE-35 support in hlsenc
From: carlos Signed-off-by: carlos --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 110 +--- libavformat/scte_35.c | 482 ++ libavformat/scte_35.h | 76 4 files changed, 646 insertions(+), 24 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index c3f38b4..93635bc 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -204,7 +204,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5dc518d..94e058e 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,7 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -203,6 +211,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -314,8 +324,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -349,11 +359,25 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_out == EVENT_OUT_CONT) { +en->adv_count = hls->scte_iface->adv_count; +hls->scte_iface->adv_count++; +en->out = hls->scte_iface->event_out; +} else { +hls->scte_iface->adv_count = 0; +en->out = hls->scte_iface->event_out; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -475,9 +499,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024] = ""; +if (hls->adv_filename) { +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, hls->adv_filename, en->out, en->adv_count, en->start_pts); +} else { +if (hls->baseurl) +strncat(fname, hls->baseurl, 1024); +strncat(fname, en->filename, 1024); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event,
Re: [FFmpeg-devel] [PATCH 1/2] v2 SCTE extraction from mpegts
On Mon, Jul 25, 2016 at 5:41 PM, Michael Niedermayer wrote: > This breaks > http://samples.ffmpeg.org/ffmpeg-bugs/trac/ticket1827/vc1_dts_mplayerAudioProblem_sb41_cut.m2ts I need some help with this. HDMV audio is not detected correctly, since we are giving priority to ISO based stream_type 817 mpegts_find_stream_type(st, pes->stream_type, ISO_types); 818 if (pes->stream_type == 4) 819 st->request_probe = 50; 820 if ((prog_reg_desc == AV_RL32("HDMV") || 821 prog_reg_desc == AV_RL32("HDPR")) && 822 st->codecpar->codec_id == AV_CODEC_ID_NONE) { 823 mpegts_find_stream_type(st, pes->stream_type, HDMV_types); In the code above we are first giving priority to ISO_types, if ffmpeg does not find any matching stream_type in ISO_types then it goes for HDMV standard. Possible solutions: a) Give more priority to HDMV and HDPR then ISO_type, b) Remove SCTE_35 codec id from ISO_type and put in MISC type a) Is correct according to the standard but there must be some reason for ISO_type being placed before HDMV. Thoughts? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/2] v3 - SCTE 35 work
- Corrected last reported issue about a sample file missing audio after these patches were applied. - Created new streamtype with SCTE Carlos (1): SCTE extraction from mpegts carlos (1): SCTE-35 support in hlsenc libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 110 --- libavformat/mpegts.c| 51 - libavformat/scte_35.c | 482 libavformat/scte_35.h | 76 7 files changed, 698 insertions(+), 30 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] v3 - SCTE extraction from mpegts
From: Carlos Signed-off-by: carlos --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavformat/mpegts.c| 51 +++-- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 3b21537..601ee5c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,6 +630,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index dea17c9..5c00be0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2950,6 +2950,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..3c2e448 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,15 +2349,20 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - -} else { +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; +} else if (tss->type == MPEGTS_PES) { int ret; // Note: The position here points actually behind the current packet. -if (tss->type == MPEGTS_PES) { -if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, +if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, pos - ts->raw_packet_size)) < 0) -return ret; -} +return ret; } return 0; @@ -2730,6 +2767,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mail
[FFmpeg-devel] [PATCH 2/2] v3 - SCTE-35 support in hlsenc
From: carlos Signed-off-by: carlos --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 110 +--- libavformat/scte_35.c | 482 ++ libavformat/scte_35.h | 76 4 files changed, 646 insertions(+), 24 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index e2cb474..7da9e67 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -204,7 +204,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5dc518d..94e058e 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,7 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -203,6 +211,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -314,8 +324,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -349,11 +359,25 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_out == EVENT_OUT_CONT) { +en->adv_count = hls->scte_iface->adv_count; +hls->scte_iface->adv_count++; +en->out = hls->scte_iface->event_out; +} else { +hls->scte_iface->adv_count = 0; +en->out = hls->scte_iface->event_out; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -475,9 +499,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024] = ""; +if (hls->adv_filename) { +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, hls->adv_filename, en->out, en->adv_count, en->start_pts); +} else { +if (hls->baseurl) +strncat(fname, hls->baseurl, 1024); +strncat(fname, en->filename, 1024); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event,
[FFmpeg-devel] [PATCH 0/2] v4 - SCTE-35 work
* Corrected reported issue (an unrelated change that made it into the patch) Carlos (1): SCTE extraction from mpegts carlos (1): SCTE-35 support in hlsenc libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 110 --- libavformat/mpegts.c| 43 - libavformat/scte_35.c | 482 libavformat/scte_35.h | 76 7 files changed, 695 insertions(+), 25 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] v4 - SCTE extraction from mpegts
From: Carlos Signed-off-by: carlos --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavformat/mpegts.c| 43 ++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 3b21537..601ee5c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,6 +630,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index dea17c9..5c00be0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2950,6 +2950,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..4185af0 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,7 +2349,14 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2769,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] v4 - SCTE-35 support in hlsenc
From: carlos Signed-off-by: carlos --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 110 +--- libavformat/scte_35.c | 482 ++ libavformat/scte_35.h | 76 4 files changed, 646 insertions(+), 24 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index fda1e17..7d47465 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -204,7 +204,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9f076ba..162fde2 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,7 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -203,6 +211,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -314,8 +324,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -349,11 +359,25 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_out == EVENT_OUT_CONT) { +en->adv_count = hls->scte_iface->adv_count; +hls->scte_iface->adv_count++; +en->out = hls->scte_iface->event_out; +} else { +hls->scte_iface->adv_count = 0; +en->out = hls->scte_iface->event_out; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -475,9 +499,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024] = ""; +if (hls->adv_filename) { +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, hls->adv_filename, en->out, en->adv_count, en->start_pts); +} else { +if (hls->baseurl) +strncat(fname, hls->baseurl, 1024); +strncat(fname, en->filename, 1024); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event,
[FFmpeg-devel] [PATCH 1/4] v5 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavcodec/version.h| 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 06c2b89..a6b9a95 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,6 +630,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index dea17c9..5c00be0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2950,6 +2950,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavcodec/version.h b/libavcodec/version.h index a697261..496b30f 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 52 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MINOR 53 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] v5 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 7c90157..a73c50d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -360,12 +360,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] v5 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 107 -- libavformat/scte_35.c | 525 ++ libavformat/scte_35.h | 86 + 4 files changed, 698 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index fda1e17..7d47465 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -204,7 +204,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9f076ba..7c90157 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1,4 +1,4 @@ -/* + /* * Apple HTTP Live Streaming segmenter * Copyright (c) 2012, Luca Barbato * @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -203,6 +212,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -314,8 +325,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -351,9 +362,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -475,9 +500,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024] = ""; +if (hls->adv_filename) { +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, hls->adv_filename, en->out, en->adv_count, en->start_pts); +} else { +if (hls->baseurl) +strncat(fname, hls->baseurl, 1024); +strncat(fname, en->filename, 1024); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, fname, en->out, -1, e
[FFmpeg-devel] [PATCH 0/4] v5 - SCTE-35 support
* Corrected all (hopefully) issues pointed out for v4. Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavcodec/version.h| 4 +- libavformat/Makefile| 2 +- libavformat/hlsenc.c| 115 --- libavformat/mpegts.c| 43 +++- libavformat/scte_35.c | 525 libavformat/scte_35.h | 86 8 files changed, 753 insertions(+), 29 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] v5 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 43 ++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..4185af0 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,7 +2349,14 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2769,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/4] v5 - Correct Indentation
On Mon, Aug 15, 2016 at 2:33 PM, Steven Liu wrote: > What dose this patch do? Addresses Michael's comment on the previous version: "this reindention is inconsistent, also you can if you like keep reindentions in a seperate patch. But if done they should be consistent" ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/4] v5 - SCTE-35 support in hlsenc
On Tue, Aug 16, 2016 at 6:39 AM, Michael Niedermayer wrote: > On Mon, Aug 15, 2016 at 10:47:49AM -0700, Carlos Fernandez Sanz wrote: >> From: Carlos Fernandez > > seems to break build > > libavformat/scte_35.c: In function ‘ff_alloc_scte35_parser’: Maybe some left overs from a previous version? The patches were generated against yesterday's git and they merge cleanly. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/4] v5 - SCTE-35 support in hlsenc
On Tue, Aug 16, 2016 at 11:13 AM, Michael Niedermayer wrote: > > in which patch is the function ? Apologies - looks like it's me who had some leftovers and didn't do a proper clean before submitting. I'll send a new patch set right away... just tested with current HEAD. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] v6 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavcodec/version.h| 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b43ee5a..d564178 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,6 +630,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index dea17c9..5c00be0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2950,6 +2950,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavcodec/version.h b/libavcodec/version.h index cdfc4f9..7ee5b5a 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 53 +#define LIBAVCODEC_VERSION_MINOR 54 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] v6 - SCTE-35
* Patchset against current HEAD - v5 didn't build cleanly. Apologies. Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavcodec/version.h| 2 +- libavformat/Makefile| 2 +- libavformat/hlsenc.c| 115 --- libavformat/mpegts.c| 43 +++- libavformat/scte_35.c | 525 libavformat/scte_35.h | 86 8 files changed, 752 insertions(+), 28 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] v6 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 107 -- libavformat/scte_35.c | 525 ++ libavformat/scte_35.h | 86 + 4 files changed, 698 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index fda1e17..7d47465 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -204,7 +204,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9f076ba..7c90157 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1,4 +1,4 @@ -/* + /* * Apple HTTP Live Streaming segmenter * Copyright (c) 2012, Luca Barbato * @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -203,6 +212,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -314,8 +325,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -351,9 +362,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -475,9 +500,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024] = ""; +if (hls->adv_filename) { +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, hls->adv_filename, en->out, en->adv_count, en->start_pts); +} else { +if (hls->baseurl) +strncat(fname, hls->baseurl, 1024); +strncat(fname, en->filename, 1024); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, fname, en->out, -1, e
[FFmpeg-devel] [PATCH 2/4] v6 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 43 ++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..4185af0 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,7 +2349,14 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2769,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] v6 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 7c90157..a73c50d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -360,12 +360,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] v7 - SCTE-35
* Corrects bug that caused crash on file matrixbench_mpeg2.mpg Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 115 --- libavformat/mpegts.c| 43 +++- libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 753 insertions(+), 27 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V7 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ 2 files changed, 7 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 6ac6646..6cdb579 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,6 +630,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] V7 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 7c90157..a73c50d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -360,12 +360,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V7 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 43 ++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..4185af0 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,7 +2349,14 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +} else if (tss->type == MPEGTS_DATA) { +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +ts->stop_parse = 1; } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2769,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V7 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 107 -- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 700 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index fda1e17..7d47465 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -204,7 +204,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9f076ba..7c90157 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1,4 +1,4 @@ -/* + /* * Apple HTTP Live Streaming segmenter * Copyright (c) 2012, Luca Barbato * @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -89,6 +94,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -104,6 +111,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -203,6 +212,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -314,8 +325,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -351,9 +362,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -475,9 +500,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024] = ""; +if (hls->adv_filename) { +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, hls->adv_filename, en->out, en->adv_count, en->start_pts); +} else { +if (hls->baseurl) +strncat(fname, hls->baseurl, 1024); +strncat(fname, en->filename, 1024); +str = hls->scte_iface->get_hls_string(hls->scte_iface, en->event, fname, en->out, -1, en
Re: [FFmpeg-devel] [PATCH 1/4] V7 - Adding SCTE-35 CUI codec
On Fri, Aug 19, 2016 at 11:48 AM, Michael Niedermayer wrote: > can you document in a comment briefly what is in the AVPackets > for most codecs that is clear, SCTE-35 is maybe a bit special > also what the dts/pts values of teh AVPackets mean Really don't know what kind of comments or where to add them... dts/pts are dts/pts :-) Can you point me to a variable or function etc that is not clear? I'll be happy to add comments but I need a bit of assistance here. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/4] V7 - Adding SCTE-35 CUI codec
On Sat, Aug 20, 2016 at 11:47 AM, Michael Niedermayer wrote: > dts are decode timestamps, that is for video thats when a packet OK, something like this? +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V8 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 3 ++- libavcodec/codec_desc.c | 6 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e2dad5d..00599c4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,7 +630,8 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, - +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V8 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 50 +- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..d000269 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,7 +2349,21 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +} else if (tss->type == MPEGTS_DATA) { +AVProgram *prg = NULL; +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, prg, idx); +if (prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { + MpegTSFilter *f = ts->pids[prg->pcr_pid]; + if(f) + ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2776,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] V8 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 25092f7..a78fdae 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -370,12 +370,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V8 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 110 --- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 702 insertions(+), 23 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 81b7efa..25092f7 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1,4 +1,4 @@ -/* + /* * Apple HTTP Live Streaming segmenter * Copyright (c) 2012, Luca Barbato * @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -91,6 +96,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -106,6 +113,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -205,6 +214,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -324,8 +335,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -361,9 +372,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -434,7 +459,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -533,9 +558,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->fi
[FFmpeg-devel] [PATCH 0/4] V8 - SCTE-35
* Used PCR for PTS and DTS of SCTE packet Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 3 +- libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 118 --- libavformat/mpegts.c| 50 - libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 763 insertions(+), 29 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V9 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 3 ++- libavcodec/codec_desc.c | 6 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e2dad5d..00599c4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,7 +630,8 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, - +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] V9 - SCTE-35
* Solves overflow reported by Steven Liu Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 3 +- libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 118 --- libavformat/mpegts.c| 50 - libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 763 insertions(+), 29 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V9 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 50 +- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..d000269 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,7 +2349,21 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +} else if (tss->type == MPEGTS_DATA) { +AVProgram *prg = NULL; +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, prg, idx); +if (prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { + MpegTSFilter *f = ts->pids[prg->pcr_pid]; + if(f) + ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2776,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V9 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 110 --- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 702 insertions(+), 23 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 81b7efa..5e2fcac 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1,4 +1,4 @@ -/* + /* * Apple HTTP Live Streaming segmenter * Copyright (c) 2012, Luca Barbato * @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -91,6 +96,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -106,6 +113,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -205,6 +214,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -324,8 +335,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -361,9 +372,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -434,7 +459,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -533,9 +558,23 @@ static int hls_window(AVFormatContext *s, int last) if (hls->flags & HLS_SINGLE_FILE) avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", en->size, en->pos); -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->fi
[FFmpeg-devel] [PATCH 4/4] V9 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5e2fcac..39a6621 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -370,12 +370,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/4] V8 - SCTE-35 support in hlsenc
On Wed, Aug 31, 2016 at 4:10 PM, Steven Liu wrote: > > Overflow here Thanks - corrected in V9 (sent a couple hours ago). Looks OK other than this? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] V10 - SCTE-35
- Addressed all issues (I think) raised by cus. Major refactor from v9 Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 3 +- libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 118 --- libavformat/mpegts.c| 64 +- libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 776 insertions(+), 30 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V10 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 3 ++- libavcodec/codec_desc.c | 6 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b174116..0eee2ab 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -630,7 +630,8 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, - +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V10 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 110 --- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 702 insertions(+), 23 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 428bae4..b210fe6 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1,4 +1,4 @@ -/* + /* * Apple HTTP Live Streaming segmenter * Copyright (c) 2012, Luca Barbato * @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -92,6 +97,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -108,6 +115,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -208,6 +217,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -327,8 +338,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -364,9 +375,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -440,7 +465,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -570,9 +595,23 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +
[FFmpeg-devel] [PATCH 4/4] V10 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index b210fe6..127b2ab 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -373,12 +373,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V10 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 64 ++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..ad6f141 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -725,6 +725,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +878,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1590,6 +1603,27 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, av_free(mp4_descr[i].dec_config_descr); } +static void scte_data_cb(MpegTSFilter *filter, const uint8_t *section, +int section_len) +{ +AVProgram *prg = NULL; +MpegTSContext *ts = filter->u.section_filter.opaque; + +int idx = ff_find_stream_index(ts->stream, filter->pid); +new_data_packet(section, section_len, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, NULL, idx); +if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { +MpegTSFilter *f = ts->pids[prg->pcr_pid]; +if(f) +ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; + +} + static const uint8_t opus_coupled_stream_cnt[9] = { 1, 0, 1, 1, 2, 2, 2, 3, 3 }; @@ -1868,6 +1902,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type return 0; } +static int is_pes_stream(int stream_type, uint32_t prog_reg_desc) +{ +return !(stream_type == 0x13 || + stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")); +} + static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; @@ -1975,7 +2015,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; -} else if (stream_type != 0x13) { + +} else if (is_pes_stream(stream_type, prog_reg_desc)) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); @@ -1994,7 +2035,9 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!st) goto out; st->id = pid; +mpegts_find_stream_type(st, stream_type, SCTE_types); st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_open_section_filter(ts, pid, scte_data_cb, ts, 1); } } @@ -2317,7 +2360,22 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - +if(0) { +AVProgram *prg = NULL; +int idx = ff_find_stream_index(ts->stream, pid); +p++; +new_data_packet(p,p_end - p, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, prg, idx); +if (prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { +MpegTSFilter *f = ts->pids[prg->pcr_pid]; +if(f) +ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; +} } else { int ret; // Note: The position here points actually behind the current packet. @@ -2730,6 +2788,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; break; } +} else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_SECTION) { +return ret; } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/4] V9 - SCTE-35 extraction from mpegts
On Sun, Sep 4, 2016 at 9:48 AM, Marton Balint wrote: > > Sorry for the delay. Below some comments. Thanks for that. I've submitted a new patch that hopefully addresses everything. Definitely much cleaner now. Carlos ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/4] V10 - SCTE-35 extraction from mpegts
On Tue, Sep 27, 2016 at 12:30 AM, Marton Balint wrote: >> +} else if (ts->pids[i] && ts->pids[i]->type == >> MPEGTS_SECTION) { >> +return ret; > > > Why do you need this hunk? I think you can delete it, and everything will > remain working. This loop flushes existing half-read PES packets, so you > cannot simply return in the middle of the loop. If we remove it we don't get SCTE-35. New patch coming up later today. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] V11 - SCTE-35 support
- Addresses all new comments - fate now passes all tests Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 2 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 116 --- libavformat/mpegts.c| 48 - libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 759 insertions(+), 28 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V11 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 2 ++ libavcodec/codec_desc.c | 6 ++ 2 files changed, 8 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b174116..e3103a1 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -631,6 +631,8 @@ enum AVCodecID { AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V11 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 48 ++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..d816450 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -725,6 +725,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +878,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1590,6 +1603,27 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, av_free(mp4_descr[i].dec_config_descr); } +static void scte_data_cb(MpegTSFilter *filter, const uint8_t *section, +int section_len) +{ +AVProgram *prg = NULL; +MpegTSContext *ts = filter->u.section_filter.opaque; + +int idx = ff_find_stream_index(ts->stream, filter->pid); +new_data_packet(section, section_len, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, NULL, idx); +if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { +MpegTSFilter *f = ts->pids[prg->pcr_pid]; +if (f) +ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; + +} + static const uint8_t opus_coupled_stream_cnt[9] = { 1, 0, 1, 1, 2, 2, 2, 3, 3 }; @@ -1868,6 +1902,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type return 0; } +static int is_pes_stream(int stream_type, uint32_t prog_reg_desc) +{ +return !(stream_type == 0x13 || + (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) ); +} + static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; @@ -1975,7 +2015,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; -} else if (stream_type != 0x13) { + +} else if (is_pes_stream(stream_type, prog_reg_desc)) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); @@ -1995,6 +2036,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len goto out; st->id = pid; st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_section_filter(ts, pid, scte_data_cb, ts, 1); +} } } @@ -2317,7 +2362,6 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - } else { int ret; // Note: The position here points actually behind the current packet. -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] V11 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 3303dc8..39d1fe9 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -373,12 +373,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V11 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 108 +-- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 701 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 428bae4..3303dc8 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -92,6 +97,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -108,6 +115,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -208,6 +217,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -327,8 +338,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -364,9 +375,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -440,7 +465,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -570,9 +595,23 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024]
Re: [FFmpeg-devel] [PATCH 2/4] V10 - SCTE-35 extraction from mpegts
On Mon, Sep 26, 2016 at 3:25 PM, Michael Niedermayer wrote: > > this breaks fate: > make: *** [fate-h264-skip-nokey] Error 1 Thanks - solved in V11. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] order T-shirts
On Tue, Sep 27, 2016 at 8:21 PM, Steven Liu wrote: >> > Hi guys, > what about the next step :-D Probably a good idea would be to have some ready for Google's Summer of Code summit... I know I'd love to get one there. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/4] V11 - SCTE-35 extraction from mpegts
On Tue, Sep 27, 2016 at 3:13 PM, Marton Balint wrote: > > nothing useful in the header, it might make sense to create a data packet > only from the buffer _after_ the section_length field, skipping the last > CRC32 field as well. I've been looking into this, but it would break some things (like base64 encoding of complete scte-35 packet) . Plus we'd miss the table_id which is not parsed in mpets.c. Next version ready (will submit now) with other things that have been mentioned here. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V12 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 2 ++ libavcodec/codec_desc.c | 6 ++ 2 files changed, 8 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index d72ee07..9064006 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -631,6 +631,8 @@ enum AVCodecID { AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] V12 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index a3224ef..1aec53f 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -406,12 +406,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V12 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 112 +-- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 705 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index c161937..a3224ef 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -92,6 +97,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -108,6 +115,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -241,6 +250,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -360,8 +371,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -397,9 +408,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -473,7 +498,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -603,9 +628,27 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024]
[FFmpeg-devel] [PATCH 2/4] V12 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 48 +++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..c13d6d8 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -725,6 +725,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +878,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1590,6 +1603,28 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, av_free(mp4_descr[i].dec_config_descr); } +static void scte_data_cb(MpegTSFilter *filter, const uint8_t *section, +int section_len) +{ +AVProgram *prg = NULL; +MpegTSContext *ts = filter->u.section_filter.opaque; + +int idx = ff_find_stream_index(ts->stream, filter->pid); +if (idx < 0) +return; + +new_data_packet(section, section_len, ts->pkt); +ts->pkt->stream_index = idx; +prg = av_find_program_from_stream(ts->stream, NULL, idx); +if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { +MpegTSFilter *f = ts->pids[prg->pcr_pid]; +if (f && f->last_pcr != -1) +ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; + +} + static const uint8_t opus_coupled_stream_cnt[9] = { 1, 0, 1, 1, 2, 2, 2, 3, 3 }; @@ -1868,6 +1903,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type return 0; } +static int is_pes_stream(int stream_type, uint32_t prog_reg_desc) +{ +return !(stream_type == 0x13 || +(stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) ); +} + static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; @@ -1975,7 +2016,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; -} else if (stream_type != 0x13) { + +} else if (is_pes_stream(stream_type, prog_reg_desc)) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); @@ -1995,6 +2037,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len goto out; st->id = pid; st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_section_filter(ts, pid, scte_data_cb, ts, 1); +} } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] V12 - SCTE-35 support
- Addresses new comments such as like idx value checking and filename checking Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 2 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 120 --- libavformat/mpegts.c| 48 - libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 764 insertions(+), 27 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] V13 - SCTE-35
- Same as V12 except for an empty that shouldn't have been there. Carlos Fernandez (4): Adding SCTE-35 CUI codec SCTE-35 extraction from mpegts SCTE-35 support in hlsenc Correct Indentation libavcodec/avcodec.h| 2 + libavcodec/codec_desc.c | 6 + libavformat/Makefile| 2 +- libavformat/hlsenc.c| 116 --- libavformat/mpegts.c| 47 - libavformat/scte_35.c | 527 libavformat/scte_35.h | 86 7 files changed, 758 insertions(+), 28 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] V13 - SCTE-35 extraction from mpegts
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/mpegts.c | 47 +-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..932ffc1 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -725,6 +725,12 @@ static const StreamType HDMV_types[] = { { 0 }, }; +/* SCTE types */ +static const StreamType SCTE_types[] = { +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, +{ 0 }, +}; + /* ATSC ? */ static const StreamType MISC_types[] = { { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, @@ -872,6 +878,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1590,6 +1603,27 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, av_free(mp4_descr[i].dec_config_descr); } +static void scte_data_cb(MpegTSFilter *filter, const uint8_t *section, +int section_len) +{ +AVProgram *prg = NULL; +MpegTSContext *ts = filter->u.section_filter.opaque; + +int idx = ff_find_stream_index(ts->stream, filter->pid); +new_data_packet(section, section_len, ts->pkt); +if (idx >= 0) { +ts->pkt->stream_index = idx; +} +prg = av_find_program_from_stream(ts->stream, NULL, idx); +if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { +MpegTSFilter *f = ts->pids[prg->pcr_pid]; +if (f) +ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; +} +ts->stop_parse = 1; + +} + static const uint8_t opus_coupled_stream_cnt[9] = { 1, 0, 1, 1, 2, 2, 2, 3, 3 }; @@ -1868,6 +1902,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type return 0; } +static int is_pes_stream(int stream_type, uint32_t prog_reg_desc) +{ +return !(stream_type == 0x13 || + (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) ); +} + static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; @@ -1975,7 +2015,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; -} else if (stream_type != 0x13) { +} else if (is_pes_stream(stream_type, prog_reg_desc)) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); @@ -1995,6 +2035,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len goto out; st->id = pid; st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +mpegts_find_stream_type(st, stream_type, SCTE_types); +mpegts_open_section_filter(ts, pid, scte_data_cb, ts, 1); +} } } @@ -2317,7 +2361,6 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - } else { int ret; // Note: The position here points actually behind the current packet. -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] V13 - Correct Indentation
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/hlsenc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 44259ec..83d6881 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -406,12 +406,12 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double else en->sub_filename[0] = '\0'; -en->duration = duration; -en->pos = pos; -en->event= event; -en->size = size; +en->duration = duration; +en->pos= pos; +en->event = event; +en->size = size; en->start_pts = start_pts; -en->next = NULL; +en->next = NULL; if (hls->scte_iface) { if (hls->scte_iface->event_state == EVENT_OUT_CONT) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] V13 - Adding SCTE-35 CUI codec
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavcodec/avcodec.h| 2 ++ libavcodec/codec_desc.c | 6 ++ 2 files changed, 8 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index d72ee07..9064006 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -631,6 +631,8 @@ enum AVCodecID { AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35,/**< Contain no valid time stamp in DTS PTS of avpacket, avpacket data contain time stamp + in scte-35 format which is relative to DTS/PTS of video stream */ AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..2612215 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2964,6 +2964,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] V13 - SCTE-35 support in hlsenc
From: Carlos Fernandez Signed-off-by: Carlos Fernandez --- libavformat/Makefile | 2 +- libavformat/hlsenc.c | 108 +-- libavformat/scte_35.c | 527 ++ libavformat/scte_35.h | 86 4 files changed, 701 insertions(+), 22 deletions(-) create mode 100644 libavformat/scte_35.c create mode 100644 libavformat/scte_35.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 5d827d31..9218606 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -205,7 +205,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o scte_35.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o OBJS-$(CONFIG_ICO_MUXER) += icoenc.o diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index c161937..44259ec 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -38,6 +38,7 @@ #include "avio_internal.h" #include "internal.h" #include "os_support.h" +#include "scte_35.h" #define KEYSIZE 16 #define LINE_BUFFER_SIZE 1024 @@ -48,6 +49,10 @@ typedef struct HLSSegment { double duration; /* in seconds */ int64_t pos; int64_t size; +struct scte_35_event *event; +int out; +int adv_count; +int64_t start_pts; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -92,6 +97,8 @@ typedef struct HLSContext { uint32_t flags;// enum HLSFlags uint32_t pl_type; // enum PlaylistType char *segment_filename; +char *adv_filename; +char *adv_subfilename; int use_localtime; ///< flag to expand filename with localtime int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename @@ -108,6 +115,8 @@ typedef struct HLSContext { int nb_entries; int discontinuity_set; +int adv_count; +struct scte_35_interface *scte_iface; HLSSegment *segments; HLSSegment *last_segment; HLSSegment *old_segments; @@ -241,6 +250,8 @@ static int hls_delete_old_segments(HLSContext *hls) { av_freep(&path); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(&previous_segment->event); av_free(previous_segment); } @@ -360,8 +371,8 @@ static int hls_mux_init(AVFormatContext *s) } /* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, + int64_t start_pts, struct scte_35_event *event, int64_t size) { HLSSegment *en = av_malloc(sizeof(*en)); char *tmp, *p; @@ -397,9 +408,23 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double en->duration = duration; en->pos = pos; +en->event= event; en->size = size; +en->start_pts = start_pts; en->next = NULL; +if (hls->scte_iface) { +if (hls->scte_iface->event_state == EVENT_OUT_CONT) { +en->adv_count = hls->adv_count;; +hls->adv_count++; +en->out = hls->scte_iface->event_state; +} else { +hls->adv_count = 0; +en->out = hls->scte_iface->event_state; +} +} + + if (hls->key_info_file) { av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); @@ -473,7 +498,7 @@ static int parse_playlist(AVFormatContext *s, const char *url) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; av_strlcpy(hls->avf->filename, line, sizeof(line)); -ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); +ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, 0, NULL, hls->size); if (ret < 0) goto fail; hls->start_pos = new_start_pos; @@ -603,9 +628,23 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } -if (hls->baseurl) -avio_printf(out, "%s", hls->baseurl); -avio_printf(out, "%s\n", en->filename); +if (hls->scte_iface && (en->event || en->out) ) { +char *str; +char fname[1024]
Re: [FFmpeg-devel] [PATCH 2/4] V12 - SCTE-35 extraction from mpegts
On Sat, Oct 1, 2016 at 10:50 AM, Marton Balint wrote: > > Empty line. Thanks, corrected in V13. If all OK, can this patchset be merged? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 0/4] V12 - SCTE-35 support
On Tue, Oct 4, 2016 at 12:11 PM, Josh de Kock wrote: > Putting SCTE35 support in another library like Upipe was suggested as well. This is something that I don't understand. Should FFmpeg just ignore the existance of this very important standard in the professional video world? Drive users to something else, even though precisely these professional users often sponsor development? > My other question would be, if it does happen to get merged, how can I > disable SCTE35 entirely? Two questions 1) Does my patch break anything? If yes - it's just not ready to be merged. 2) SCTE-35, by its very definition, it's to cue video rebroadcasters to switch from one stream to another in real time, for example to add local commercials during a break. It's not a consumer format and you are just not going to see SCTE-35 in any stream "in the wild". By the time the stream reaches the consumer SCTE-35 has already done its job. However if you do deal with a stream that contains SCTE-35 data most likely you don't want to ignore it. Or maybe I'm just missing some real world scenarios? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Start of SCTE-35 support [PATCH]
Hi, This patch starts the work on SCTE-35 support; for now it just detects SCTE-35 and if present sends the data to a dummy function. Since it's my first contribution to ffmpeg I preferred to start small and continue working as small pieces of work are accepted or commented. Carlos 0001-SCTE-extraction-from-mpegts.patch Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Start of SCTE-35 support [PATCH]
Hi, Apologies for resending - gmail sent the first attempt as a binary attachment. This patch starts the work on SCTE-35 support; for now it just detects SCTE-35 and if present sends the data to a dummy function. Since it's my first contribution to ffmpeg I preferred to start small and continue working as small pieces of work are accepted or commented. Carlos From c0166b6d74945ef3f2121e97215c1455f9408eaf Mon Sep 17 00:00:00 2001 From: Carlos Date: Mon, 11 Jan 2016 23:27:37 -0800 Subject: [PATCH] SCTE extraction from mpegts Signed-off-by: carlos --- libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 6 ++ libavformat/mpegts.c| 42 -- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 39713ed..3a3c2fc 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -628,6 +628,7 @@ enum AVCodecID { /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. AV_CODEC_ID_TTF = 0x18000, +AV_CODEC_ID_SCTE_35, AV_CODEC_ID_BINTEXT= 0x18800, AV_CODEC_ID_XBIN, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 9d94b72..59fd261 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2949,6 +2949,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_SCTE_35, +.type = AVMEDIA_TYPE_DATA, +.name = "scte_35", +.long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), +}, /* deprecated codec ids */ }; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b31d233..467f1de 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -57,6 +57,7 @@ enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, +MPEGTS_DATA, }; typedef struct MpegTSFilter MpegTSFilter; @@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) return mpegts_open_filter(ts, pid, MPEGTS_PCR); } +static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid) +{ +return mpegts_open_filter(ts, pid, MPEGTS_DATA); +} + static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) { int pid; @@ -705,6 +711,7 @@ static const StreamType ISO_types[] = { { 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 }, { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, +{ 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35}, { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1}, { 0 }, @@ -872,6 +879,13 @@ static void reset_pes_packet_state(PESContext *pes) av_buffer_unref(&pes->buffer); } +static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) +{ +av_init_packet(pkt); +pkt->data = buffer; +pkt->size = len; +} + static int new_pes_packet(PESContext *pes, AVPacket *pkt) { char *sd; @@ -1975,6 +1989,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len pes->st->id = pes->pid; } st = pes->st; +} else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) { +int idx = ff_find_stream_index(ts->stream, pid); +if (idx >= 0) { +st = ts->stream->streams[idx]; +} else { +st = avformat_new_stream(ts->stream, NULL); +if (!st) +goto out; +st->id = pid; +st->codecpar->codec_type = AVMEDIA_TYPE_DATA; +mpegts_find_stream_type(st, stream_type, ISO_types); +mpegts_open_data_filter(ts, pid); +} } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably @@ -2317,15 +2344,16 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) } } } - -} else { +} else if (tss->type == MPEGTS_DATA) { +p++; +new_data_packet(p,p_end - p, ts->pkt); +ts->stop_parse = 1; +} else if (tss->type == MPEGTS_PES) { int ret; // Note: The position here points actually behind the current packet. -if (tss->type == MPEGTS_PES) { -if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, +if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, pos - ts->raw_packet_size)) < 0) -return ret; -} +