[FFmpeg-devel] [PATCH] libavformat/dashenc: add an option to the dash muxer to create smaller manifests during live streams

Mathias Lacaud mlacaud at quanteec.com
Wed Mar 16 16:35:27 EET 2022


Add an option 'live_window_size' which sets the maximum number of 
segments kept in the manifest during the transcoding. At the end, all of 
the segments are written in the manifest. Ignored if window_size is not 
set to 0. This option may be used to create smaller manifests during 
live streams and then get the full manifest at the end for offline replay.

Signed-off-by: Mathias Lacaud (mlacaud) <matlaca24 at gmail.com>
---
  doc/muxers.texi       |  2 ++
  libavformat/dashenc.c | 13 +++++++++----
  2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 1af603b7f6..0153a069ff 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -277,6 +277,8 @@ Set the type of interval for fragmentation.
  Set the maximum number of segments kept in the manifest.
  @item extra_window_size @var{size}
  Set the maximum number of segments kept outside of the manifest before 
removing from disk.
+ at item live_window_size @var{size}
+Set the maximum number of segments kept in the manifest during the 
transcoding. At the end, all of the segments are written in the 
manifest. Ignored if @var{window_size} is not set to 0. Use this option 
to create smaller manifests during live streams and then get the full 
manifest at the end for offline replay.
  @item remove_at_exit @var{remove}
  Enable (1) or disable (0) removal of all segments when finished.
  @item use_template @var{template}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 9a97838f5c..f381b47aab 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -148,6 +148,7 @@ typedef struct DASHContext {
      int nb_as;
      int window_size;
      int extra_window_size;
+    int live_window_size;
      int64_t seg_duration;
      int64_t frag_duration;
      int remove_at_exit;
@@ -493,12 +494,15 @@ static void get_hls_playlist_name(char 
*playlist_name, int string_size,
  }
   static void get_start_index_number(OutputStream *os, DASHContext *c,
-                                   int *start_index, int *start_number) {
+                                   int *start_index, int *start_number, 
int final) {
      *start_index = 0;
      *start_number = 1;
      if (c->window_size) {
          *start_index  = FFMAX(os->nb_segments   - c->window_size, 0);
          *start_number = FFMAX(os->segment_index - c->window_size, 1);
+    } else if (c->live_window_size && !final) {
+        *start_index  = FFMAX(os->nb_segments   - c->live_window_size, 0);
+        *start_number = FFMAX(os->segment_index - c->live_window_size, 1);
      }
  }
  @@ -517,7 +521,7 @@ static void write_hls_media_playlist(OutputStream 
*os, AVFormatContext *s,
      int i, start_index, start_number;
      double prog_date_time = 0;
  -    get_start_index_number(os, c, &start_index, &start_number);
+    get_start_index_number(os, c, &start_index, &start_number, final);
       if (!c->hls_playlist || start_index >= os->nb_segments ||
          os->segment_type != SEGMENT_TYPE_MP4)
@@ -645,7 +649,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
  {
      DASHContext *c = s->priv_data;
      int i, start_index, start_number;
-    get_start_index_number(os, c, &start_index, &start_number);
+    get_start_index_number(os, c, &start_index, &start_number, final);
       if (c->use_template) {
          int timescale = c->use_timeline ? 
os->ctx->streams[0]->time_base.den : AV_TIME_BASE;
@@ -2010,7 +2014,7 @@ static int dash_flush(AVFormatContext *s, int 
final, int stream)
                  if (c->global_sidx) {
                      int j, start_index, start_number;
                      int64_t sidx_size = avio_tell(os->ctx->pb) - 
file_size;
-                    get_start_index_number(os, c, &start_index, 
&start_number);
+                    get_start_index_number(os, c, &start_index, 
&start_number, final);
                      if (start_index >= os->nb_segments ||
                          os->segment_type != SEGMENT_TYPE_MP4)
                          continue;
@@ -2361,6 +2365,7 @@ static const AVOption options[] = {
      { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 
id=1,streams=3,4 and so on", OFFSET(adaptation_sets), 
AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
      { "window_size", "number of segments kept in the manifest", 
OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
      { "extra_window_size", "number of segments kept outside of the 
manifest before removing from disk", OFFSET(extra_window_size), 
AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
+    { "live_window_size", "number of segments kept in the live 
manifests (only if window_size is set to 0)", OFFSET(live_window_size), 
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
      { "seg_duration", "segment duration (in seconds, fractional value 
can be set)", OFFSET(seg_duration), AV_OPT_TYPE_DURATION, { .i64 = 
5000000 }, 0, INT_MAX, E },
      { "frag_duration", "fragment duration (in seconds, fractional 
value can be set)", OFFSET(frag_duration), AV_OPT_TYPE_DURATION, { .i64 
= 0 }, 0, INT_MAX, E },
      { "frag_type", "set type of interval for fragments", 
OFFSET(frag_type), AV_OPT_TYPE_INT, {.i64 = FRAG_TYPE_NONE }, 0, 
FRAG_TYPE_NB - 1, E, "frag_type"},
-- 
2.17.1



More information about the ffmpeg-devel mailing list