summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishwanath Dixit <vdixit@akamai.com>2018-02-19 11:25:36 +0530
committerKarthick Jeyapal <kjeyapal@akamai.com>2018-02-24 10:55:28 +0530
commit28924f4b488a2a22c2a1e41706fd97b6e484325c (patch)
tree11581f6134eb8f7ba91420e530940166e04eb79a
parentffe7cc89d0ce352fd9e67283d6a949eaa98f46a4 (diff)
downloadffmpeg-streaming-28924f4b488a2a22c2a1e41706fd97b6e484325c.zip
ffmpeg-streaming-28924f4b488a2a22c2a1e41706fd97b6e484325c.tar.gz
avformat/dashenc: chunk streaming support for low latency use cases
-rw-r--r--doc/muxers.texi3
-rw-r--r--libavformat/dashenc.c26
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, &buffer);
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(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
+ if (c->streaming)
+ av_dict_set(&opts, "movflags", "frag_every_frame+dash+delay_moov", 0);
+ else
+ av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
} else {
av_dict_set_int(&opts, "cluster_time_limit", c->min_seg_duration / 1000, 0);
av_dict_set_int(&opts, "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(&opts);
}
+ //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, &buf);
+ 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 },
};
OpenPOWER on IntegriCloud