Re: [FFmpeg-devel] [PATCH 3/3] avformat/dashenc: chunk streaming support for low latency use cases

2018-02-23 Thread Jeyapal, Karthick


On 2/19/18 11:25 AM, vdi...@akamai.com wrote:
> From: Vishwanath Dixit 
>
> ---
>  doc/muxers.texi   |  3 +++
>  libavformat/dashenc.c | 26 +++---
>  2 files changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index d9a5cc0..c156ec0 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -254,6 +254,9 @@ Use persistent HTTP connections. Applicable only for HTTP 
> output.
>  @item -hls_playlist @var{hls_playlist}
>  Generate HLS playlist files as well. The master playlist is generated with 
> the filename master.m3u8.
>  One media playlist file is generated for each stream with filenames 
> media_0.m3u8, media_1.m3u8, etc.
> +@item -streaming @var{streaming}
> +Enable (1) or disable (0) chunk streaming mode of output. In chunk streaming
> +mode, each frame will be a moof fragment which forms a chunk.
>  @item -adaptation_sets @var{adaptation_sets}
>  Assign streams to AdaptationSets. Syntax is "id=x,streams=a,b,c 
> id=y,streams=d,e" with x and y being the IDs
>  of the adaptation sets and a,b,c,d and e are the indices of the mapped 
> streams.
> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
> index 0eb4b25..d6474f3 100644
> --- a/libavformat/dashenc.c
> +++ b/libavformat/dashenc.c
> @@ -81,6 +81,7 @@ typedef struct OutputStream {
>  char bandwidth_str[64];
>  
>  char codec_str[100];
> +int written_len;
>  char filename[1024];
>  char full_path[1024];
>  char temp_path[1024];
> @@ -114,6 +115,7 @@ typedef struct DASHContext {
>  int master_playlist_created;
>  AVIOContext *mpd_out;
>  AVIOContext *m3u8_out;
> +int streaming;
>  } DASHContext;
>  
>  static struct codec_string {
> @@ -250,7 +252,8 @@ static int flush_dynbuf(OutputStream *os, int 
> *range_length)
>  // write out to file
>  *range_length = avio_close_dyn_buf(os->ctx->pb, );
>  os->ctx->pb = NULL;
> -avio_write(os->out, buffer, *range_length);
> +avio_write(os->out, buffer + os->written_len, *range_length - 
> os->written_len);
> +os->written_len = 0;
>  av_free(buffer);
>  
>  // re-open buffer
> @@ -960,7 +963,10 @@ static int dash_init(AVFormatContext *s)
>  os->init_start_pos = 0;
>  
>  if (!strcmp(os->format_name, "mp4")) {
> -av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 0);
> +if (c->streaming)
> +av_dict_set(, "movflags", 
> "frag_every_frame+dash+delay_moov", 0);
> +else
> +av_dict_set(, "movflags", 
> "frag_custom+dash+delay_moov", 0);
>  } else {
>  av_dict_set_int(, "cluster_time_limit", c->min_seg_duration 
> / 1000, 0);
>  av_dict_set_int(, "cluster_size_limit", 5 * 1024 * 1024, 
> 0); // set a large cluster size limit
> @@ -1155,7 +1161,7 @@ static int dash_flush(AVFormatContext *s, int final, 
> int stream)
>  }
>  
>  if (!c->single_file) {
> -if (!strcmp(os->format_name, "mp4"))
> +if (!strcmp(os->format_name, "mp4") && !os->written_len)
>  write_styp(os->ctx->pb);
>  } else {
>  snprintf(os->full_path, sizeof(os->full_path), "%s%s", 
> c->dirname, os->initfile);
> @@ -1318,6 +1324,19 @@ static int dash_write_packet(AVFormatContext *s, 
> AVPacket *pkt)
>  av_dict_free();
>  }
>  
> +//write out the data immediately in streaming mode
> +if (c->streaming && !strcmp(os->format_name, "mp4")) {
> +int len = 0;
> +uint8_t *buf = NULL;
> +if (!os->written_len)
> +write_styp(os->ctx->pb);
> +avio_flush(os->ctx->pb);
> +len = avio_get_dyn_buf (os->ctx->pb, );
> +avio_write(os->out, buf + os->written_len, len - os->written_len);
> +os->written_len = len;
> +avio_flush(os->out);
> +}
> +
>  return ret;
>  }
>  
> @@ -1394,6 +1413,7 @@ static const AVOption options[] = {
>  { "http_user_agent", "override User-Agent field in HTTP header", 
> OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
>  { "http_persistent", "Use persistent HTTP connections", 
> OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
>  { "hls_playlist", "Generate HLS playlist files(master.m3u8, 
> media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 
> E },
> +{ "streaming", "Enable/Disable streaming mode of output. Each frame will 
> be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E 
> },
>  { NULL },
>  };
>  
Patchset pushed.

Regards,
Karthick


___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/3] avformat/dashenc: chunk streaming support for low latency use cases

2018-02-18 Thread vdixit
From: Vishwanath Dixit 

---
 doc/muxers.texi   |  3 +++
 libavformat/dashenc.c | 26 +++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index d9a5cc0..c156ec0 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -254,6 +254,9 @@ Use persistent HTTP connections. Applicable only for HTTP 
output.
 @item -hls_playlist @var{hls_playlist}
 Generate HLS playlist files as well. The master playlist is generated with the 
filename master.m3u8.
 One media playlist file is generated for each stream with filenames 
media_0.m3u8, media_1.m3u8, etc.
+@item -streaming @var{streaming}
+Enable (1) or disable (0) chunk streaming mode of output. In chunk streaming
+mode, each frame will be a moof fragment which forms a chunk.
 @item -adaptation_sets @var{adaptation_sets}
 Assign streams to AdaptationSets. Syntax is "id=x,streams=a,b,c 
id=y,streams=d,e" with x and y being the IDs
 of the adaptation sets and a,b,c,d and e are the indices of the mapped streams.
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 0eb4b25..d6474f3 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -81,6 +81,7 @@ typedef struct OutputStream {
 char bandwidth_str[64];
 
 char codec_str[100];
+int written_len;
 char filename[1024];
 char full_path[1024];
 char temp_path[1024];
@@ -114,6 +115,7 @@ typedef struct DASHContext {
 int master_playlist_created;
 AVIOContext *mpd_out;
 AVIOContext *m3u8_out;
+int streaming;
 } DASHContext;
 
 static struct codec_string {
@@ -250,7 +252,8 @@ static int flush_dynbuf(OutputStream *os, int *range_length)
 // write out to file
 *range_length = avio_close_dyn_buf(os->ctx->pb, );
 os->ctx->pb = NULL;
-avio_write(os->out, buffer, *range_length);
+avio_write(os->out, buffer + os->written_len, *range_length - 
os->written_len);
+os->written_len = 0;
 av_free(buffer);
 
 // re-open buffer
@@ -960,7 +963,10 @@ static int dash_init(AVFormatContext *s)
 os->init_start_pos = 0;
 
 if (!strcmp(os->format_name, "mp4")) {
-av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 0);
+if (c->streaming)
+av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov", 0);
+else
+av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
 } else {
 av_dict_set_int(, "cluster_time_limit", c->min_seg_duration / 
1000, 0);
 av_dict_set_int(, "cluster_size_limit", 5 * 1024 * 1024, 0); 
// set a large cluster size limit
@@ -1155,7 +1161,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 }
 
 if (!c->single_file) {
-if (!strcmp(os->format_name, "mp4"))
+if (!strcmp(os->format_name, "mp4") && !os->written_len)
 write_styp(os->ctx->pb);
 } else {
 snprintf(os->full_path, sizeof(os->full_path), "%s%s", c->dirname, 
os->initfile);
@@ -1318,6 +1324,19 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 av_dict_free();
 }
 
+//write out the data immediately in streaming mode
+if (c->streaming && !strcmp(os->format_name, "mp4")) {
+int len = 0;
+uint8_t *buf = NULL;
+if (!os->written_len)
+write_styp(os->ctx->pb);
+avio_flush(os->ctx->pb);
+len = avio_get_dyn_buf (os->ctx->pb, );
+avio_write(os->out, buf + os->written_len, len - os->written_len);
+os->written_len = len;
+avio_flush(os->out);
+}
+
 return ret;
 }
 
@@ -1394,6 +1413,7 @@ static const AVOption options[] = {
 { "http_user_agent", "override User-Agent field in HTTP header", 
OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
 { "http_persistent", "Use persistent HTTP connections", 
OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
 { "hls_playlist", "Generate HLS playlist files(master.m3u8, 
media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E 
},
+{ "streaming", "Enable/Disable streaming mode of output. Each frame will 
be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
 { NULL },
 };
 
-- 
1.9.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel