[FFmpeg-devel] [PATCH 2/3] Add a new hls_flag peak_segment_bw

Amit Kale amitk at hotstar.com
Mon Feb 12 10:54:09 EET 2018


If this flag is set, BANDWIDTH value in a master playlist entry will be 
set to
the peak segment bandwidth.
---
  doc/muxers.texi      |  4 ++++
  libavformat/hlsenc.c | 29 +++++++++++++++++++++--------
  2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index d9a5cc03dc..e2c9cbfa2f 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -741,6 +741,10 @@ subdirectories.
  Possible values:

  @table @samp
+ at item peak_segment_bw
+If this flag is set, BANDWIDTH value in a master playlist entry will be
+set to the peak segment bandwidth.
+
  @item single_file
  If this flag is set, the muxer will store all segments in a single MPEG-TS
  file, and will use byte ranges in the playlist. HLS playlists 
generated with
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 9970c4c575..f40cd0b98f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -98,6 +98,7 @@ typedef enum HLSFlags {
      HLS_TEMP_FILE = (1 << 11),
      HLS_PERIODIC_REKEY = (1 << 12),
      HLS_INDEPENDENT_SEGMENTS = (1 << 13),
+    HLS_PEAK_SEGMENT_BW = (1 << 14),
  } HLSFlags;

  typedef enum {
@@ -1168,7 +1169,8 @@ static int get_relative_url(const char 
*master_url, const char *media_url,
  }

  static int create_master_playlist(AVFormatContext *s,
-                                  VariantStream * const input_vs)
+                                  VariantStream * const input_vs,
+                                  int last)
  {
      HLSContext *hls = s->priv_data;
      VariantStream *vs, *temp_vs;
@@ -1185,7 +1187,7 @@ static int create_master_playlist(AVFormatContext *s,
          for (i = 0; i < hls->nb_varstreams; i++)
              if (!hls->var_streams[i].m3u8_created)
                  return 0;
-    } else {
+    } else if (!last) {
           /* Keep publishing the master playlist at the configured rate */
          if (&hls->var_streams[0] != input_vs || 
!hls->master_publish_rate ||
              input_vs->number % hls->master_publish_rate)
@@ -1292,11 +1294,21 @@ static int 
create_master_playlist(AVFormatContext *s,
          }

          bandwidth = 0;
-        if (vid_st)
-            bandwidth += vid_st->codecpar->bit_rate;
-        if (aud_st)
-            bandwidth += aud_st->codecpar->bit_rate;
-        bandwidth += bandwidth / 10;
+        if (last && hls->flags & HLS_PEAK_SEGMENT_BW) {
+            HLSSegment *hs = vs->segments;
+            while (hs) {
+                int64_t segment_bandwidth = hs->size * 8 / hs->duration;
+                if (bandwidth < segment_bandwidth)
+                    bandwidth = segment_bandwidth;
+                hs = hs->next;
+            }
+        } else {
+            if (vid_st)
+                bandwidth += vid_st->codecpar->bit_rate;
+            if (aud_st)
+                bandwidth += aud_st->codecpar->bit_rate;
+            bandwidth += bandwidth / 10;
+        }

          ccgroup = NULL;
          if (vid_st && vs->ccgroup) {
@@ -1437,7 +1449,7 @@ fail:
          ff_rename(temp_filename, vs->m3u8_name, s);

      if (ret >= 0 && hls->master_pl_name)
-        if (create_master_playlist(s, vs) < 0)
+        if (create_master_playlist(s, vs, last) < 0)
              av_log(s, AV_LOG_WARNING, "Master playlist creation 
failed\n");

      return ret;
@@ -2753,6 +2765,7 @@ static const AVOption options[] = {
      {"fmp4",   "make segment file to fragment mp4 files in m3u8", 0, 
AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_FMP4 }, 0, UINT_MAX, E, 
"segment_type"},
      {"hls_fmp4_init_filename", "set fragment mp4 file init filename", 
OFFSET(fmp4_init_filename),   AV_OPT_TYPE_STRING, {.str = 
"init.mp4"},            0,       0,         E},
      {"hls_flags",     "set flags affecting HLS playlist and media file 
generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, 
E, "flags"},
+    {"peak_segment_bw",   "sets bandwidth in master play list to peak 
segment bandwidth", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PEAK_SEGMENT_BW }, 
0, UINT_MAX,   E, "flags"},
      {"single_file",   "generate a single media file indexed with byte 
ranges", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SINGLE_FILE }, 0, UINT_MAX,   
E, "flags"},
      {"temp_file", "write segment to temporary file and rename when 
complete", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_TEMP_FILE }, 0, UINT_MAX,   
E, "flags"},
      {"delete_segments", "delete segment files that are no longer part 
of the playlist", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DELETE_SEGMENTS }, 
0, UINT_MAX,   E, "flags"},
-- 
2.14.1




More information about the ffmpeg-devel mailing list