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 Sanzwrote: > 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(); > previous_segment = segment; > segment = previous_segment->next; > +if (hls->scte_iface) > +hls->scte_iface->unref_scte35_event(_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",
[FFmpeg-devel] [PATCH 3/4] V14 - SCTE-35 support in hlsenc
From: Carlos FernandezSigned-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(); previous_segment = segment; segment = previous_segment->next; +if (hls->scte_iface) +hls->scte_iface->unref_scte35_event(_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",