Re: [FFmpeg-devel] [PATCH 3/4] V14 - SCTE-35 support in hlsenc

2016-10-31 Thread Carlos Fernandez Sanz
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();
>  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

2016-10-18 Thread Carlos Fernandez Sanz
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", 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",