diff mbox

[FFmpeg-devel,v3] avformat/hlsenc: Added option to add EXT-X-INDEPENDENT-SEGMENTS tag

Message ID 1511436806-12127-1-git-send-email-kjeyapal@akamai.com
State Accepted
Commit efb51c8ebbe21f701da816bb78aefc0ce98b378d
Headers show

Commit Message

Jeyapal, Karthick Nov. 23, 2017, 11:33 a.m. UTC
---
 doc/muxers.texi      |  4 ++++
 libavformat/hlsenc.c | 17 +++++++++++++++++
 2 files changed, 21 insertions(+)

Comments

Steven Liu Nov. 23, 2017, 11:01 p.m. UTC | #1
2017-11-23 19:33 GMT+08:00 Karthick J <kjeyapal@akamai.com>:
> ---
>  doc/muxers.texi      |  4 ++++
>  libavformat/hlsenc.c | 17 +++++++++++++++++
>  2 files changed, 21 insertions(+)
>
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index 0bb8ad2..9d9ca31 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -737,6 +737,10 @@ The file specified by @code{hls_key_info_file} will be checked periodically and
>  detect updates to the encryption info. Be sure to replace this file atomically,
>  including the file containing the AES encryption key.
>
> +@item independent_segments
> +Add the @code{#EXT-X-INDEPENDENT-SEGMENTS} to playlists that has video segments
> +and when all the segments of that playlist are guaranteed to start with a Key frame.
> +
>  @item split_by_time
>  Allow segments to start on frames other than keyframes. This improves
>  behavior on some players when the time between keyframes is inconsistent,
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index 3c47ced..3010714 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -88,6 +88,7 @@ typedef enum HLSFlags {
>      HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime  e.g.: %%014s
>      HLS_TEMP_FILE = (1 << 11),
>      HLS_PERIODIC_REKEY = (1 << 12),
> +    HLS_INDEPENDENT_SEGMENTS = (1 << 13),
>  } HLSFlags;
>
>  typedef enum {
> @@ -1191,6 +1192,10 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
>          sequence = 0;
>      }
>
> +    if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
> +        hls->version = 6;
> +    }
> +
>      if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>          hls->version = 7;
>      }
> @@ -1220,6 +1225,9 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
>          avio_printf(out, "#EXT-X-DISCONTINUITY\n");
>          vs->discontinuity_set = 1;
>      }
> +    if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
> +        avio_printf(out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
> +    }
>      for (en = vs->segments; en; en = en->next) {
>          if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
>                                      av_strcasecmp(en->iv_string, iv_string))) {
> @@ -1732,6 +1740,14 @@ static int hls_write_header(AVFormatContext *s)
>      vs->start_pts      = AV_NOPTS_VALUE;
>      vs->current_segment_final_filename_fmt[0] = '\0';
>
> +    if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
> +        // Independent segments cannot be guaranteed when splitting by time
> +        hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
> +        av_log(s, AV_LOG_WARNING,
> +               "'split_by_time' and 'independent_segments' cannot be enabled together. "
> +               "Disabling 'independent_segments' flag\n");
> +    }
> +
>      if (hls->flags & HLS_PROGRAM_DATE_TIME) {
>          time_t now0;
>          time(&now0);
> @@ -2323,6 +2339,7 @@ static const AVOption options[] = {
>      {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX,   E, "flags"},
>      {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX,   E, "flags"},
>      {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX,   E, "flags"},
> +    {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
>      {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
>      {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
>      {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" },
> --
> 1.9.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Pushed


Thanks
Jeyapal, Karthick Nov. 24, 2017, 2:57 a.m. UTC | #2
On 11/24/17, 4:31 AM, "Steven Liu" <lingjiujianke@gmail.com> wrote:

>Pushed

Thanks.
>

>

>Thanks


regards,
Karthick
diff mbox

Patch

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 0bb8ad2..9d9ca31 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -737,6 +737,10 @@  The file specified by @code{hls_key_info_file} will be checked periodically and
 detect updates to the encryption info. Be sure to replace this file atomically,
 including the file containing the AES encryption key.
 
+@item independent_segments
+Add the @code{#EXT-X-INDEPENDENT-SEGMENTS} to playlists that has video segments
+and when all the segments of that playlist are guaranteed to start with a Key frame.
+
 @item split_by_time
 Allow segments to start on frames other than keyframes. This improves
 behavior on some players when the time between keyframes is inconsistent,
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 3c47ced..3010714 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -88,6 +88,7 @@  typedef enum HLSFlags {
     HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime  e.g.: %%014s
     HLS_TEMP_FILE = (1 << 11),
     HLS_PERIODIC_REKEY = (1 << 12),
+    HLS_INDEPENDENT_SEGMENTS = (1 << 13),
 } HLSFlags;
 
 typedef enum {
@@ -1191,6 +1192,10 @@  static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
         sequence = 0;
     }
 
+    if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
+        hls->version = 6;
+    }
+
     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
         hls->version = 7;
     }
@@ -1220,6 +1225,9 @@  static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
         avio_printf(out, "#EXT-X-DISCONTINUITY\n");
         vs->discontinuity_set = 1;
     }
+    if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
+        avio_printf(out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
+    }
     for (en = vs->segments; en; en = en->next) {
         if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
                                     av_strcasecmp(en->iv_string, iv_string))) {
@@ -1732,6 +1740,14 @@  static int hls_write_header(AVFormatContext *s)
     vs->start_pts      = AV_NOPTS_VALUE;
     vs->current_segment_final_filename_fmt[0] = '\0';
 
+    if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
+        // Independent segments cannot be guaranteed when splitting by time
+        hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
+        av_log(s, AV_LOG_WARNING,
+               "'split_by_time' and 'independent_segments' cannot be enabled together. "
+               "Disabling 'independent_segments' flag\n");
+    }
+
     if (hls->flags & HLS_PROGRAM_DATE_TIME) {
         time_t now0;
         time(&now0);
@@ -2323,6 +2339,7 @@  static const AVOption options[] = {
     {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX,   E, "flags"},
     {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX,   E, "flags"},
+    {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
     {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
     {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
     {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" },