[FFmpeg-devel] [PATCH] avformat/dashenc: Fix a bug with writing "final" manifest

2019-04-16 Thread Karthick J via ffmpeg-devel
This bug was introduced in the commit 951561b64ee6c11f01daedd9dcf73276cc1e765b
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5f1333e436..b88d4b3496 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1631,7 +1631,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 }
 }
 if (ret >= 0) {
-if (c->has_video) {
+if (c->has_video && !final) {
 c->nr_of_streams_flushed++;
 if (c->nr_of_streams_flushed != c->nr_of_streams_to_flush)
 return ret;
-- 
2.20.1 (Apple Git-117)

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] avformat/dashenc: Disable streaming for webm output

2019-04-10 Thread Karthick J via ffmpeg-devel
Currently streaming for webm output doesn't work.
Disabling explicitly will make sure that the manifest will get generated 
correctly.
---
 libavformat/dashenc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index f8d71166d4..d8dcbc1230 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1200,6 +1200,11 @@ static int dash_init(AVFormatContext *s)
"Override -init_seg_name and/or -media_seg_name and/or "
"-single_file_name to end with the extension .webm\n");
 }
+if (c->streaming) {
+// Streaming not supported as matroskaenc buffers internally 
before writing the output
+av_log(s, AV_LOG_WARNING, "One or more streams in WebM output 
format. Streaming option will be ignored\n");
+c->streaming = 0;
+}
 }
 
 ctx->oformat = av_guess_format(os->format_name, NULL, NULL);
-- 
2.20.1 (Apple Git-117)

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] avformat/dashenc : Fix streaming mode support for webm output

2019-04-08 Thread Karthick J via ffmpeg-devel
---
 libavformat/dashenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index f8d71166d4..9dd520787f 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1750,10 +1750,10 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 }
 
 //write out the data immediately in streaming mode
-if (c->streaming && os->segment_type == SEGMENT_TYPE_MP4) {
+if (c->streaming) {
 int len = 0;
 uint8_t *buf = NULL;
-if (!os->written_len)
+if (!os->written_len && os->segment_type == SEGMENT_TYPE_MP4)
 write_styp(os->ctx->pb);
 avio_flush(os->ctx->pb);
 len = avio_get_dyn_buf (os->ctx->pb, );
-- 
2.20.1 (Apple Git-117)

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Add support for Global SIDX

2019-03-24 Thread Karthick J via ffmpeg-devel
---
 doc/muxers.texi   |   3 ++
 libavformat/dashenc.c | 119 --
 2 files changed, 84 insertions(+), 38 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index aac7d94edf..83ae017d6c 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -293,6 +293,9 @@ Set container format (mp4/webm) options using a @code{:} 
separated list of
 key=value parameters. Values containing @code{:} special characters must be
 escaped.
 
+@item -global_sidx @var{global_sidx}
+Write global SIDX atom. Applicable only for single file, mp4 output, 
non-streaming mode.
+
 @item -dash_segment_type @var{dash_segment_type}
 Possible values:
 @item auto
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 1b74bce060..f8d71166d4 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -140,6 +140,7 @@ typedef struct DASHContext {
 int64_t timeout;
 int index_correction;
 char *format_options_str;
+int global_sidx;
 SegmentType segment_type_option;  /* segment type as specified in options 
*/
 int ignore_io_errors;
 int lhls;
@@ -368,7 +369,7 @@ static void set_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
 }
 }
 
-static int flush_dynbuf(OutputStream *os, int *range_length)
+static int flush_dynbuf(DASHContext *c, OutputStream *os, int *range_length)
 {
 uint8_t *buffer;
 
@@ -380,16 +381,21 @@ static int flush_dynbuf(OutputStream *os, int 
*range_length)
 av_write_frame(os->ctx, NULL);
 avio_flush(os->ctx->pb);
 
-// write out to file
-*range_length = avio_close_dyn_buf(os->ctx->pb, );
-os->ctx->pb = NULL;
-if (os->out)
-avio_write(os->out, buffer + os->written_len, *range_length - 
os->written_len);
-os->written_len = 0;
-av_free(buffer);
-
-// re-open buffer
-return avio_open_dyn_buf(>ctx->pb);
+if (!c->single_file) {
+// write out to file
+*range_length = avio_close_dyn_buf(os->ctx->pb, );
+os->ctx->pb = NULL;
+if (os->out)
+avio_write(os->out, buffer + os->written_len, *range_length - 
os->written_len);
+os->written_len = 0;
+av_free(buffer);
+
+// re-open buffer
+return avio_open_dyn_buf(>ctx->pb);
+} else {
+*range_length = avio_tell(os->ctx->pb) - os->pos;
+return 0;
+}
 }
 
 static void set_http_options(AVDictionary **options, DASHContext *c)
@@ -508,7 +514,7 @@ static int flush_init_segment(AVFormatContext *s, 
OutputStream *os)
 DASHContext *c = s->priv_data;
 int ret, range_length;
 
-ret = flush_dynbuf(os, _length);
+ret = flush_dynbuf(c, os, _length);
 if (ret < 0)
 return ret;
 
@@ -537,8 +543,12 @@ static void dash_free(AVFormatContext *s)
 return;
 for (i = 0; i < s->nb_streams; i++) {
 OutputStream *os = >streams[i];
-if (os->ctx && os->ctx->pb)
-ffio_free_dyn_buf(>ctx->pb);
+if (os->ctx && os->ctx->pb) {
+if (!c->single_file)
+ffio_free_dyn_buf(>ctx->pb);
+else
+avio_close(os->ctx->pb);
+}
 ff_format_io_close(s, >out);
 if (os->ctx)
 avformat_free_context(os->ctx);
@@ -1106,6 +1116,16 @@ static int dash_init(AVFormatContext *s)
 c->lhls = 0;
 }
 
+if (c->global_sidx && !c->single_file) {
+av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as 
single_file is not enabled\n");
+c->global_sidx = 0;
+}
+
+if (c->global_sidx && c->streaming) {
+av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as 
streaming is enabled\n");
+c->global_sidx = 0;
+}
+
 av_strlcpy(c->dirname, s->url, sizeof(c->dirname));
 ptr = strrchr(c->dirname, '/');
 if (ptr) {
@@ -1201,9 +1221,6 @@ static int dash_init(AVFormatContext *s)
 ctx->avoid_negative_ts = s->avoid_negative_ts;
 ctx->flags = s->flags;
 
-if ((ret = avio_open_dyn_buf(>pb)) < 0)
-return ret;
-
 if (c->single_file) {
 if (os->single_file_name)
 ff_dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), 
os->single_file_name, i, 0, os->bit_rate, 0);
@@ -1214,7 +1231,14 @@ static int dash_init(AVFormatContext *s)
 }
 snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
 set_http_options(, c);
-ret = s->io_open(s, >out, filename, AVIO_FLAG_WRITE, );
+if (!c->single_file) {
+if ((ret = avio_open_dyn_buf(>pb)) < 0)
+return ret;
+ret = s->io_open(s, >out, filename, AVIO_FLAG_WRITE, );
+} else {
+ctx->url = av_strdup(filename);
+ret = avio_open2(>pb, filename, AVIO_FLAG_WRITE, NULL, );
+}
 av_dict_free();
 if (ret < 0)
 return ret;
@@ -1232,8 +1256,12 @@ static int dash_init(AVFormatContext *s)
 // skip_sidx : 

[FFmpeg-devel] [PATCH 1/2] avformat/movenc: Fix skip_trailer when global_sidx is enabled

2019-03-24 Thread Karthick J via ffmpeg-devel
---
 libavformat/movenc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 8969d5b170..f46cbc5ea5 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -6745,9 +6745,8 @@ static int mov_write_trailer(AVFormatContext *s)
 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
 mov_write_sidx_tags(pb, mov, -1, 0);
 avio_seek(pb, end, SEEK_SET);
-avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
-mov_write_mfra_tag(pb, mov);
-} else if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
+}
+if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
 mov_write_mfra_tag(pb, mov);
 }
-- 
2.17.2 (Apple Git-113)

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Added comments

2019-02-20 Thread Karthick J
Added comments regarding usage of certain movflags in streaming mode.
---
 libavformat/dashenc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index a0b44a0ec3..c5e882f4ae 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1216,6 +1216,9 @@ static int dash_init(AVFormatContext *s)
 
 if (os->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
+// frag_every_frame : Allows lower latency streaming
+// skip_sidx : Reduce bitrate overhead
+// skip_trailer : Avoids growing memory usage with time
 av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+skip_sidx+skip_trailer", 0);
 else
 av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Added comments

2019-02-18 Thread Karthick J
Added comments regarding usage of certain movflags in streaming mode.
---
 libavformat/dashenc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index a0b44a0ec3..f8782756b4 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1216,6 +1216,17 @@ static int dash_init(AVFormatContext *s)
 
 if (os->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
+// Explanation for why certain movflags are used for streaming:
+// frag_every_frame :- Every frame should be moof fragment, so
+// the data from current frame can be streamed without
+// waiting for the completion of the entire segment.
+// skip_sidx :- The SIDX atom for each moof will result in a
+// significant bitrate overhead. Hence disabling it here.
+// skip_trailer :- Writing mp4 trailer means that a list of all
+// fragment's information is stored, which results 
continuous
+// growth in memory usage as more fragments are muxed.
+// Disabling trailer results in deterministic memory usage.
+// Anyways trailer is unnecessary of fmp4 segment.
 av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+skip_sidx+skip_trailer", 0);
 else
 av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Added option to repeatedly publish master playlist

2019-02-18 Thread Karthick J
The master playlist can be published at a specified interval with this option
---
 doc/muxers.texi   | 3 +++
 libavformat/dashenc.c | 9 -
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 36010cf2d1..372fab2f92 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -315,6 +315,9 @@ This option will also try to comply with the above open 
spec, till Apple's spec
 Applicable only when @var{streaming} and @var{hls_playlist} options are 
enabled.
 This is an experimental feature.
 
+@item -master_m3u8_publish_rate @var{master_m3u8_publish_rate}
+Publish master playlist repeatedly every after specified number of segment 
intervals.
+
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 37a7547b12..a0b44a0ec3 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -141,6 +141,7 @@ typedef struct DASHContext {
 SegmentType segment_type_option;  /* segment type as specified in options 
*/
 int ignore_io_errors;
 int lhls;
+int master_publish_rate;
 } DASHContext;
 
 static struct codec_string {
@@ -965,13 +966,18 @@ static int write_manifest(AVFormatContext *s, int final)
 return ret;
 }
 
-if (c->hls_playlist && !c->master_playlist_created) {
+if (c->hls_playlist) {
 char filename_hls[1024];
 const char *audio_group = "A1";
 char audio_codec_str[128] = "\0";
 int is_default = 1;
 int max_audio_bitrate = 0;
 
+// Publish master playlist only the configured rate
+if (c->master_playlist_created && (!c->master_publish_rate ||
+ c->streams[0].segment_index % c->master_publish_rate))
+return 0;
+
 if (*c->dirname)
 snprintf(filename_hls, sizeof(filename_hls), "%smaster.m3u8", 
c->dirname);
 else
@@ -1798,6 +1804,7 @@ static const AVOption options[] = {
 { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 
= SEGMENT_TYPE_WEBM }, 0, UINT_MAX,   E, "segment_type"},
 { "ignore_io_errors", "Ignore IO errors during open and write. Useful for 
long-duration runs with network output", OFFSET(ignore_io_errors), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
 { "lhls", "Enable Low-latency HLS(Experimental). Adds #EXT-X-PREFETCH tag 
with current segment's URI", OFFSET(lhls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 
1, E },
+{ "master_m3u8_publish_rate", "Publish master playlist every after this 
many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 
0}, 0, UINT_MAX, E},
 { NULL },
 };
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/tee : Pass standards compliance value to slave muxers as well

2019-01-30 Thread Karthick J
---
 libavformat/tee.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/tee.c b/libavformat/tee.c
index ef3b113a47..89a4ceb280 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -236,6 +236,7 @@ static int open_slave(AVFormatContext *avf, char *slave, 
TeeSlave *tee_slave)
 avf2->io_close = avf->io_close;
 avf2->interrupt_callback = avf->interrupt_callback;
 avf2->flags = avf->flags;
+avf2->strict_std_compliance = avf->strict_std_compliance;
 
 tee_slave->stream_map = av_calloc(avf->nb_streams, 
sizeof(*tee_slave->stream_map));
 if (!tee_slave->stream_map) {
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Skip writing trailer for MP4 output when in streaming mode

2019-01-23 Thread Karthick J
In streaming mode mp4 trailer is not required for playout.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 9c90cf17e5..6299e179c2 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1210,7 +1210,7 @@ static int dash_init(AVFormatContext *s)
 
 if (os->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
-av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+skip_sidx", 0);
+av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+skip_sidx+skip_trailer", 0);
 else
 av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
 } else {
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Added documentation for $ext$ identifier in filenames

2019-01-17 Thread Karthick J
---
 doc/muxers.texi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 4ed46a2220..d2d985f1ac 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -216,6 +216,8 @@ It creates a MPD manifest file and segment files for each 
stream.
 The segment filename might contain pre-defined identifiers used with 
SegmentTemplate
 as defined in section 5.3.9.4.4 of the standard. Available identifiers are 
"$RepresentationID$",
 "$Number$", "$Bandwidth$" and "$Time$".
+In addition to the standard identifiers, an ffmpeg-specific "$ext$" identifier 
is also supported.
+When specified ffmpeg will replace $ext$ in the file name with muxing format's 
extensions such as mp4, webm etc.,
 
 @example
 ffmpeg -re -i  -map 0 -map 0 -c:a libfdk_aac -c:v libx264
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2] avformat/dashenc: Format xs:datetime in millisecond precision

2019-01-17 Thread Karthick J
For low latency streaming even milliseconds matter!
---
 libavformat/dashenc.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index cfd0f601d4..9c90cf17e5 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -32,6 +32,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/rational.h"
+#include "libavutil/time.h"
 #include "libavutil/time_internal.h"
 
 #include "avc.h"
@@ -668,12 +669,20 @@ static void write_time(AVIOContext *out, int64_t time)
 
 static void format_date_now(char *buf, int size)
 {
-time_t t = time(NULL);
 struct tm *ptm, tmbuf;
-ptm = gmtime_r(, );
+int64_t time_us = av_gettime();
+int64_t time_ms = time_us / 1000;
+const time_t time_s = time_ms / 1000;
+int millisec = time_ms - (time_s * 1000);
+ptm = gmtime_r(_s, );
 if (ptm) {
-if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%SZ", ptm))
+int len;
+if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%S", ptm)) {
 buf[0] = '\0';
+return;
+}
+len = strlen(buf);
+snprintf(buf + len, size - len, ".%03dZ", millisec);
 }
 }
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Format xs:datetime in millisecond precision

2019-01-17 Thread Karthick J
For low latency streaming even milliseconds matter!
---
 libavformat/dashenc.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index cfd0f601d4..912c1cf11d 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -32,6 +32,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/rational.h"
+#include "libavutil/time.h"
 #include "libavutil/time_internal.h"
 
 #include "avc.h"
@@ -668,12 +669,18 @@ static void write_time(AVIOContext *out, int64_t time)
 
 static void format_date_now(char *buf, int size)
 {
-time_t t = time(NULL);
 struct tm *ptm, tmbuf;
-ptm = gmtime_r(, );
+int64_t time_us = av_gettime();
+int64_t time_ms = time_us / 1000;
+const time_t time_s = time_ms / 1000;
+int millisec = time_ms - (time_s * 1000);
+ptm = gmtime_r(_s, );
 if (ptm) {
-if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%SZ", ptm))
+int len;
+if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%S", ptm))
 buf[0] = '\0';
+len = strlen(buf);
+snprintf(buf + len, size - len, ".%03dZ", millisec);
 }
 }
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/file: Fix file delete for Windows

2018-12-30 Thread Karthick J
From: Karthick Jeyapal 

Fixes bug id : 7638
---
 libavformat/file.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavformat/file.c b/libavformat/file.c
index 1d321c4..e613b91 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -173,7 +173,11 @@ static int file_delete(URLContext *h)
 av_strstart(filename, "file:", );
 
 ret = rmdir(filename);
-if (ret < 0 && errno == ENOTDIR)
+if (ret < 0 && (errno == ENOTDIR
+#   ifdef _WIN32
+|| errno == EINVAL
+#   endif
+))
 ret = unlink(filename);
 if (ret < 0)
 return AVERROR(errno);
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/dashenc : Refactored HLS media playlist related code

2018-12-12 Thread Karthick J
Made it as a separate function, so that it could be reused (in future)
---
 libavformat/dashenc.c | 135 +++---
 1 file changed, 75 insertions(+), 60 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 585b34cb97..f797b7bd1c 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -407,6 +407,78 @@ static void get_hls_playlist_name(char *playlist_name, int 
string_size,
 snprintf(playlist_name, string_size, "media_%d.m3u8", id);
 }
 
+static void get_start_index_number(OutputStream *os, DASHContext *c,
+   int *start_index, int *start_number) {
+*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);
+}
+}
+
+static void write_hls_media_playlist(OutputStream *os, AVFormatContext *s,
+ int representation_id, int final) {
+DASHContext *c = s->priv_data;
+int timescale = os->ctx->streams[0]->time_base.den;
+char temp_filename_hls[1024];
+char filename_hls[1024];
+AVDictionary *http_opts = NULL;
+int target_duration = 0;
+int ret = 0;
+const char *proto = avio_find_protocol_name(c->dirname);
+int use_rename = proto && !strcmp(proto, "file");
+int i, start_index, start_number;
+
+get_start_index_number(os, c, _index, _number);
+get_hls_playlist_name(filename_hls, sizeof(filename_hls),
+  c->dirname, representation_id);
+
+snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
+
+set_http_options(_opts, c);
+ret = dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
+av_dict_free(_opts);
+if (ret < 0) {
+handle_io_open_error(s, ret, temp_filename_hls);
+return;
+}
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+double duration = (double) seg->duration / timescale;
+if (target_duration <= duration)
+target_duration = lrint(duration);
+}
+
+ff_hls_write_playlist_header(c->m3u8_out, 6, -1, target_duration,
+ start_number, PLAYLIST_TYPE_NONE);
+
+ff_hls_write_init_file(c->m3u8_out, os->initfile, c->single_file,
+   os->init_range_length, os->init_start_pos);
+
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+ret = ff_hls_write_file_entry(c->m3u8_out, 0, c->single_file,
+(double) seg->duration / timescale, 0,
+seg->range_length, seg->start_pos, NULL,
+c->single_file ? os->initfile : seg->file,
+NULL);
+if (ret < 0) {
+av_log(os->ctx, AV_LOG_WARNING, "ff_hls_write_file_entry get 
error\n");
+}
+}
+
+if (final)
+ff_hls_write_end_list(c->m3u8_out);
+
+dashenc_io_close(s, >m3u8_out, temp_filename_hls);
+
+if (use_rename)
+if (avpriv_io_move(temp_filename_hls, filename_hls) < 0) {
+av_log(os->ctx, AV_LOG_WARNING, "renaming file %s to %s 
failed\n\n", temp_filename_hls, filename_hls);
+}
+}
+
 static int flush_init_segment(AVFormatContext *s, OutputStream *os)
 {
 DASHContext *c = s->priv_data;
@@ -463,11 +535,8 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 int representation_id, int final)
 {
 DASHContext *c = s->priv_data;
-int i, 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);
-}
+int i, start_index, start_number;
+get_start_index_number(os, c, _index, _number);
 
 if (c->use_template) {
 int timescale = c->use_timeline ? os->ctx->streams[0]->time_base.den : 
AV_TIME_BASE;
@@ -527,61 +596,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 }
 if (c->hls_playlist && start_index < os->nb_segments && os->segment_type 
== SEGMENT_TYPE_MP4)
 {
-int timescale = os->ctx->streams[0]->time_base.den;
-char temp_filename_hls[1024];
-char filename_hls[1024];
-AVDictionary *http_opts = NULL;
-int target_duration = 0;
-int ret = 0;
-const char *proto = avio_find_protocol_name(c->dirname);
-int use_rename = proto && !strcmp(proto, "file");
-
-get_hls_playlist_name(filename_hls, sizeof(filename_hls),
-  c->dirname, representation_id);
-
-snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
-
-

[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Added support for Low-latency HLS(Experimental)

2018-12-12 Thread Karthick J
Apple doesn't have an official spec for LHLS. Meanwhile hls.js player folks are
trying to standardize a open LHLS spec. The draft spec is available in 
https://github.com/video-dev/hlsjs-rfcs/blob/lhls-spec/proposals/0001-lhls.md
This option will also try to comply with the above open spec, till Apple's spec 
officially supports it.
Applicable only when @var{streaming} and @var{hls_playlist} options are enabled.
---
 doc/muxers.texi   |  8 
 libavformat/dashenc.c | 37 +
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 809f88662e..4ed46a2220 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -305,6 +305,14 @@ If this flag is set, the dash segment files will be in in 
WebM format.
 @item -ignore_io_errors @var{ignore_io_errors}
 Ignore IO errors during open and write. Useful for long-duration runs with 
network output.
 
+@item -lhls @var{lhls}
+Enable Low-latency HLS(LHLS). Adds #EXT-X-PREFETCH tag with current segment's 
URI.
+Apple doesn't have an official spec for LHLS. Meanwhile hls.js player folks are
+trying to standardize a open LHLS spec. The draft spec is available in 
https://github.com/video-dev/hlsjs-rfcs/blob/lhls-spec/proposals/0001-lhls.md
+This option will also try to comply with the above open spec, till Apple's 
spec officially supports it.
+Applicable only when @var{streaming} and @var{hls_playlist} options are 
enabled.
+This is an experimental feature.
+
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index f797b7bd1c..cfd0f601d4 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -139,6 +139,7 @@ typedef struct DASHContext {
 char *format_options_str;
 SegmentType segment_type_option;  /* segment type as specified in options 
*/
 int ignore_io_errors;
+int lhls;
 } DASHContext;
 
 static struct codec_string {
@@ -418,7 +419,8 @@ static void get_start_index_number(OutputStream *os, 
DASHContext *c,
 }
 
 static void write_hls_media_playlist(OutputStream *os, AVFormatContext *s,
- int representation_id, int final) {
+ int representation_id, int final,
+ char *prefetch_url) {
 DASHContext *c = s->priv_data;
 int timescale = os->ctx->streams[0]->time_base.den;
 char temp_filename_hls[1024];
@@ -431,6 +433,11 @@ static void write_hls_media_playlist(OutputStream *os, 
AVFormatContext *s,
 int i, start_index, start_number;
 
 get_start_index_number(os, c, _index, _number);
+
+if (!c->hls_playlist || start_index >= os->nb_segments ||
+os->segment_type != SEGMENT_TYPE_MP4)
+return;
+
 get_hls_playlist_name(filename_hls, sizeof(filename_hls),
   c->dirname, representation_id);
 
@@ -468,6 +475,9 @@ static void write_hls_media_playlist(OutputStream *os, 
AVFormatContext *s,
 }
 }
 
+if (prefetch_url)
+avio_printf(c->m3u8_out, "#EXT-X-PREFETCH:%s\n", prefetch_url);
+
 if (final)
 ff_hls_write_end_list(c->m3u8_out);
 
@@ -594,9 +604,8 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 }
 avio_printf(out, "\t\t\t\t\n");
 }
-if (c->hls_playlist && start_index < os->nb_segments && os->segment_type 
== SEGMENT_TYPE_MP4)
-{
-write_hls_media_playlist(os, s, representation_id, final);
+if (!c->lhls || final) {
+write_hls_media_playlist(os, s, representation_id, final, NULL);
 }
 
 }
@@ -1054,6 +1063,21 @@ static int dash_init(AVFormatContext *s)
 c->seg_duration = c->min_seg_duration;
 }
 #endif
+if (c->lhls && s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+av_log(s, AV_LOG_ERROR,
+   "LHLS is experimental, Please set -strict experimental in order 
to enable it.\n");
+return AVERROR_EXPERIMENTAL;
+}
+
+if (c->lhls && !c->streaming) {
+av_log(s, AV_LOG_WARNING, "LHLS option will be ignored as streaming is 
not enabled\n");
+c->lhls = 0;
+}
+
+if (c->lhls && !c->hls_playlist) {
+av_log(s, AV_LOG_WARNING, "LHLS option will be ignored as hls_playlist 
is not enabled\n");
+c->lhls = 0;
+}
 
 av_strlcpy(c->dirname, s->url, sizeof(c->dirname));
 ptr = strrchr(c->dirname, '/');
@@ -1635,6 +1659,10 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 if (ret < 0) {
 return handle_io_open_error(s, ret, os->temp_path);
 }
+if (c->lhls) {
+char *prefetch_url = use_rename ? NULL : os->filename;
+write_hls_media_playlist(os, s, pkt->stream_index, 0, 
prefetch_url);
+}
 }
 
 //write out the data immediately in streaming mode
@@ -1760,6 +1788,7 @@ static const AVOption options[] = {
 { "mp4", "make segment file in ISOBMFF format", 0, 

[FFmpeg-devel] [PATCH 1/2] avformat/dashenc : Refactored HLS media playlist related code

2018-12-11 Thread Karthick J
Made it as a separate function, so that it could be reused (in future)
---
 libavformat/dashenc.c | 135 +++---
 1 file changed, 75 insertions(+), 60 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 585b34cb97..f797b7bd1c 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -407,6 +407,78 @@ static void get_hls_playlist_name(char *playlist_name, int 
string_size,
 snprintf(playlist_name, string_size, "media_%d.m3u8", id);
 }
 
+static void get_start_index_number(OutputStream *os, DASHContext *c,
+   int *start_index, int *start_number) {
+*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);
+}
+}
+
+static void write_hls_media_playlist(OutputStream *os, AVFormatContext *s,
+ int representation_id, int final) {
+DASHContext *c = s->priv_data;
+int timescale = os->ctx->streams[0]->time_base.den;
+char temp_filename_hls[1024];
+char filename_hls[1024];
+AVDictionary *http_opts = NULL;
+int target_duration = 0;
+int ret = 0;
+const char *proto = avio_find_protocol_name(c->dirname);
+int use_rename = proto && !strcmp(proto, "file");
+int i, start_index, start_number;
+
+get_start_index_number(os, c, _index, _number);
+get_hls_playlist_name(filename_hls, sizeof(filename_hls),
+  c->dirname, representation_id);
+
+snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
+
+set_http_options(_opts, c);
+ret = dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
+av_dict_free(_opts);
+if (ret < 0) {
+handle_io_open_error(s, ret, temp_filename_hls);
+return;
+}
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+double duration = (double) seg->duration / timescale;
+if (target_duration <= duration)
+target_duration = lrint(duration);
+}
+
+ff_hls_write_playlist_header(c->m3u8_out, 6, -1, target_duration,
+ start_number, PLAYLIST_TYPE_NONE);
+
+ff_hls_write_init_file(c->m3u8_out, os->initfile, c->single_file,
+   os->init_range_length, os->init_start_pos);
+
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+ret = ff_hls_write_file_entry(c->m3u8_out, 0, c->single_file,
+(double) seg->duration / timescale, 0,
+seg->range_length, seg->start_pos, NULL,
+c->single_file ? os->initfile : seg->file,
+NULL);
+if (ret < 0) {
+av_log(os->ctx, AV_LOG_WARNING, "ff_hls_write_file_entry get 
error\n");
+}
+}
+
+if (final)
+ff_hls_write_end_list(c->m3u8_out);
+
+dashenc_io_close(s, >m3u8_out, temp_filename_hls);
+
+if (use_rename)
+if (avpriv_io_move(temp_filename_hls, filename_hls) < 0) {
+av_log(os->ctx, AV_LOG_WARNING, "renaming file %s to %s 
failed\n\n", temp_filename_hls, filename_hls);
+}
+}
+
 static int flush_init_segment(AVFormatContext *s, OutputStream *os)
 {
 DASHContext *c = s->priv_data;
@@ -463,11 +535,8 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 int representation_id, int final)
 {
 DASHContext *c = s->priv_data;
-int i, 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);
-}
+int i, start_index, start_number;
+get_start_index_number(os, c, _index, _number);
 
 if (c->use_template) {
 int timescale = c->use_timeline ? os->ctx->streams[0]->time_base.den : 
AV_TIME_BASE;
@@ -527,61 +596,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 }
 if (c->hls_playlist && start_index < os->nb_segments && os->segment_type 
== SEGMENT_TYPE_MP4)
 {
-int timescale = os->ctx->streams[0]->time_base.den;
-char temp_filename_hls[1024];
-char filename_hls[1024];
-AVDictionary *http_opts = NULL;
-int target_duration = 0;
-int ret = 0;
-const char *proto = avio_find_protocol_name(c->dirname);
-int use_rename = proto && !strcmp(proto, "file");
-
-get_hls_playlist_name(filename_hls, sizeof(filename_hls),
-  c->dirname, representation_id);
-
-snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
-
-

[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Added support for Low-latency HLS(LHLS)

2018-12-11 Thread Karthick J
Apple doesn't have an official spec for LHLS. Meanwhile hls.js player folks are
trying to standardize a open LHLS spec. The draft spec is available in 
https://github.com/video-dev/hlsjs-rfcs/blob/lhls-spec/proposals/0001-lhls.md
This option will also try to comply with the above open spec, till Apple's spec 
officially supports it.
Applicable only when @var{streaming} and @var{hls_playlist} options are enabled.
---
 doc/muxers.texi   |  7 +++
 libavformat/dashenc.c | 31 +++
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 809f88662e..f09a89db82 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -305,6 +305,13 @@ If this flag is set, the dash segment files will be in in 
WebM format.
 @item -ignore_io_errors @var{ignore_io_errors}
 Ignore IO errors during open and write. Useful for long-duration runs with 
network output.
 
+@item -lhls @var{lhls}
+Enable Low-latency HLS(LHLS). Adds #EXT-X-PREFETCH tag with current segment's 
URI.
+Apple doesn't have an official spec for LHLS. Meanwhile hls.js player folks are
+trying to standardize a open LHLS spec. The draft spec is available in 
https://github.com/video-dev/hlsjs-rfcs/blob/lhls-spec/proposals/0001-lhls.md
+This option will also try to comply with the above open spec, till Apple's 
spec officially supports it.
+Applicable only when @var{streaming} and @var{hls_playlist} options are 
enabled.
+
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index f797b7bd1c..8685642437 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -139,6 +139,7 @@ typedef struct DASHContext {
 char *format_options_str;
 SegmentType segment_type_option;  /* segment type as specified in options 
*/
 int ignore_io_errors;
+int lhls;
 } DASHContext;
 
 static struct codec_string {
@@ -418,7 +419,8 @@ static void get_start_index_number(OutputStream *os, 
DASHContext *c,
 }
 
 static void write_hls_media_playlist(OutputStream *os, AVFormatContext *s,
- int representation_id, int final) {
+ int representation_id, int final,
+ char *prefetch_url) {
 DASHContext *c = s->priv_data;
 int timescale = os->ctx->streams[0]->time_base.den;
 char temp_filename_hls[1024];
@@ -431,6 +433,11 @@ static void write_hls_media_playlist(OutputStream *os, 
AVFormatContext *s,
 int i, start_index, start_number;
 
 get_start_index_number(os, c, _index, _number);
+
+if (!c->hls_playlist || start_index >= os->nb_segments ||
+os->segment_type != SEGMENT_TYPE_MP4)
+return;
+
 get_hls_playlist_name(filename_hls, sizeof(filename_hls),
   c->dirname, representation_id);
 
@@ -468,6 +475,9 @@ static void write_hls_media_playlist(OutputStream *os, 
AVFormatContext *s,
 }
 }
 
+if (prefetch_url)
+avio_printf(c->m3u8_out, "#EXT-X-PREFETCH:%s\n", prefetch_url);
+
 if (final)
 ff_hls_write_end_list(c->m3u8_out);
 
@@ -594,9 +604,8 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 }
 avio_printf(out, "\t\t\t\t\n");
 }
-if (c->hls_playlist && start_index < os->nb_segments && os->segment_type 
== SEGMENT_TYPE_MP4)
-{
-write_hls_media_playlist(os, s, representation_id, final);
+if (!c->lhls || final) {
+write_hls_media_playlist(os, s, representation_id, final, NULL);
 }
 
 }
@@ -1054,6 +1063,15 @@ static int dash_init(AVFormatContext *s)
 c->seg_duration = c->min_seg_duration;
 }
 #endif
+if (c->lhls && !c->streaming) {
+av_log(s, AV_LOG_WARNING, "LHLS option will be ignored as streaming is 
not enabled\n");
+c->lhls = 0;
+}
+
+if (c->lhls && !c->hls_playlist) {
+av_log(s, AV_LOG_WARNING, "LHLS option will be ignored as hls_playlist 
is not enabled\n");
+c->lhls = 0;
+}
 
 av_strlcpy(c->dirname, s->url, sizeof(c->dirname));
 ptr = strrchr(c->dirname, '/');
@@ -1635,6 +1653,10 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 if (ret < 0) {
 return handle_io_open_error(s, ret, os->temp_path);
 }
+if (c->lhls) {
+char *prefetch_url = use_rename ? NULL : os->filename;
+write_hls_media_playlist(os, s, pkt->stream_index, 0, 
prefetch_url);
+}
 }
 
 //write out the data immediately in streaming mode
@@ -1760,6 +1782,7 @@ static const AVOption options[] = {
 { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, 
{.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX,   E, "segment_type"},
 { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 
= SEGMENT_TYPE_WEBM }, 0, UINT_MAX,   E, "segment_type"},
 { "ignore_io_errors", "Ignore IO errors during open and write. Useful for 

[FFmpeg-devel] [PATCH 2/2] avformat/hlsenc : Added an option to ignore IO errors

2018-12-06 Thread Karthick J
Useful for long duration runs with network output
---
 doc/muxers.texi  |  3 +++
 libavformat/hlsenc.c | 41 +++--
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index ca10741900..8eefcf1e82 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1018,6 +1018,9 @@ Use persistent HTTP connections. Applicable only for HTTP 
output.
 @item timeout
 Set timeout for socket I/O operations. Applicable only for HTTP output.
 
+@item -ignore_io_errors
+Ignore IO errors during open, write and delete. Useful for long-duration runs 
with network output.
+
 @end table
 
 @anchor{ico}
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 42adcfbab1..bdd2a113bd 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -227,6 +227,7 @@ typedef struct HLSContext {
 AVIOContext *m3u8_out;
 AVIOContext *sub_m3u8_out;
 int64_t timeout;
+int ignore_io_errors;
 } HLSContext;
 
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
@@ -496,8 +497,11 @@ static int hls_delete_old_segments(AVFormatContext *s, 
HLSContext *hls,
 proto = avio_find_protocol_name(s->url);
 if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
 av_dict_set(, "method", "DELETE", 0);
-if ((ret = vs->avf->io_open(vs->avf, , path, AVIO_FLAG_WRITE, 
)) < 0)
+if ((ret = vs->avf->io_open(vs->avf, , path, AVIO_FLAG_WRITE, 
)) < 0) {
+if (hls->ignore_io_errors)
+ret = 0;
 goto fail;
+}
 ff_format_io_close(vs->avf, );
 } else if (unlink(path) < 0) {
 av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
@@ -525,6 +529,8 @@ static int hls_delete_old_segments(AVFormatContext *s, 
HLSContext *hls,
 if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
 av_dict_set(, "method", "DELETE", 0);
 if ((ret = vs->vtt_avf->io_open(vs->vtt_avf, , sub_path, 
AVIO_FLAG_WRITE, )) < 0) {
+if (hls->ignore_io_errors)
+ret = 0;
 av_free(sub_path);
 goto fail;
 }
@@ -1380,8 +1386,11 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 
 set_http_options(s, , hls);
 snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : 
"%s", vs->m3u8_name);
-if ((ret = hlsenc_io_open(s, >m3u8_out, temp_filename, )) < 0)
+if ((ret = hlsenc_io_open(s, >m3u8_out, temp_filename, )) < 
0) {
+if (hls->ignore_io_errors)
+ret = 0;
 goto fail;
+}
 
 for (en = vs->segments; en; en = en->next) {
 if (target_duration <= en->duration)
@@ -1428,8 +1437,11 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 ff_hls_write_end_list(hls->m3u8_out);
 
 if( vs->vtt_m3u8_name ) {
-if ((ret = hlsenc_io_open(s, >sub_m3u8_out, vs->vtt_m3u8_name, 
)) < 0)
+if ((ret = hlsenc_io_open(s, >sub_m3u8_out, vs->vtt_m3u8_name, 
)) < 0) {
+if (hls->ignore_io_errors)
+ret = 0;
 goto fail;
+}
 ff_hls_write_playlist_header(hls->sub_m3u8_out, hls->version, 
hls->allowcache,
  target_duration, sequence, 
PLAYLIST_TYPE_NONE);
 for (en = vs->segments; en; en = en->next) {
@@ -1452,7 +1464,6 @@ fail:
 hlsenc_io_close(s, >sub_m3u8_out, vs->vtt_m3u8_name);
 if (use_temp_file)
 ff_rename(temp_filename, vs->m3u8_name, s);
-
 if (ret >= 0 && hls->master_pl_name)
 if (create_master_playlist(s, vs) < 0)
 av_log(s, AV_LOG_WARNING, "Master playlist creation failed\n");
@@ -1611,13 +1622,19 @@ static int hls_start(AVFormatContext *s, VariantStream 
*vs)
 if (err < 0)
 return err;
 } else if (c->segment_type != SEGMENT_TYPE_FMP4) {
-if ((err = hlsenc_io_open(s, >pb, oc->url, )) < 0)
+if ((err = hlsenc_io_open(s, >pb, oc->url, )) < 0) {
+if (c->ignore_io_errors)
+err = 0;
 goto fail;
+}
 }
 if (vs->vtt_basename) {
 set_http_options(s, , c);
-if ((err = hlsenc_io_open(s, _oc->pb, vtt_oc->url, )) < 0)
+if ((err = hlsenc_io_open(s, _oc->pb, vtt_oc->url, )) < 0) 
{
+if (c->ignore_io_errors)
+err = 0;
 goto fail;
+}
 }
 av_dict_free();
 
@@ -2257,9 +2274,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 set_http_options(s, , hls);
 ret = hlsenc_io_open(s, >out, vs->avf->url, );
 if (ret < 0) {
-av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n",
-   vs->avf->url);
-return ret;
+

[FFmpeg-devel] [PATCH 1/2] avformat/hlsenc: Handled error from ff_http_do_new_request() function

2018-12-06 Thread Karthick J
This patch fixes the segmentation fault issues due to unhandled errors from 
ff_http_do_new_request function.
---
 libavformat/hlsenc.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 31ef0237ae..42adcfbab1 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -241,6 +241,9 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 URLContext *http_url_context = ffio_geturlcontext(*pb);
 av_assert0(http_url_context);
 err = ff_http_do_new_request(http_url_context, filename);
+if (err < 0)
+ff_format_io_close(s, pb);
+
 #endif
 }
 return err;
@@ -249,6 +252,8 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
 HLSContext *hls = s->priv_data;
 int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
+if (!*pb)
+return;
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
 #if CONFIG_HTTP_PROTOCOL
@@ -2329,7 +2334,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 }
 
 vs->packets_written++;
-ret = ff_write_chained(oc, stream_index, pkt, s, 0);
+if (oc->pb)
+ret = ff_write_chained(oc, stream_index, pkt, s, 0);
 
 return ret;
 }
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v4] avformat/movenc: Added an option to disable SIDX atom

2018-12-05 Thread Karthick J
---
 doc/muxers.texi  |  4 
 libavformat/movenc.c | 12 ++--
 libavformat/movenc.h |  1 +
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index f1cc6f5fee..ca10741900 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1325,6 +1325,10 @@ more efficient), but with this option set, the muxer 
writes one moof/mdat
 pair for each track, making it easier to separate tracks.
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
+@item -movflags skip_sidx
+Skip writing of sidx atom. When bitrate overhead due to sidx atom is high,
+this option could be used for cases where sidx atom is not mandatory.
+When global_sidx flag is enabled, this option will be ignored. 
 @item -movflags faststart
 Run a second pass moving the index (moov atom) to the beginning of the file.
 This operation can take a while, and will not work in various situations such
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6dab5193b0..28cf8b719c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -75,6 +75,7 @@ static const AVOption options[] = {
 { "frag_discont", "Signal that the next fragment is discontinuous from 
earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, 
INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
 { "delay_moov", "Delay writing the initial moov until the first fragment 
is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "global_sidx", "Write a global sidx index at the start of the file", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+{ "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_colr", "Write colr atom (Experimental, may be renamed or changed, 
do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 
= FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "use_metadata_tags", "Use mdta atom for metadata.", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
@@ -4603,7 +4604,8 @@ static int mov_write_moof_tag(AVIOContext *pb, 
MOVMuxContext *mov, int tracks,
 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
 moof_size = ffio_close_null_buf(avio_buf);
 
-if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX))
+if (mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | FF_MOV_FLAG_SKIP_SIDX)))
 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
 
 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
@@ -5422,7 +5424,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * the next fragment. This means the cts of the first sample must
  * be the same in all fragments, unless end_pts was updated by
  * the packet causing the fragment to be written. */
-if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX)) ||
+if ((mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | 
FF_MOV_FLAG_SKIP_SIDX))) ||
 mov->mode == MODE_ISM)
 pkt->pts = pkt->dts + trk->end_pts - 
trk->cluster[trk->entry].dts;
 } else {
@@ -6067,6 +6070,11 @@ static int mov_init(AVFormatContext *s)
 s->flags &= ~AVFMT_FLAG_AUTO_BSF;
 }
 
+if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX && mov->flags & 
FF_MOV_FLAG_SKIP_SIDX) {
+av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx 
option\n");
+mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
+}
+
 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
 mov->reserved_moov_size = -1;
 }
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index fe605d1ad2..68d6f23a5a 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -257,6 +257,7 @@ typedef struct MOVMuxContext {
 #define FF_MOV_FLAG_SKIP_TRAILER  (1 << 18)
 #define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS  (1 << 19)
 #define FF_MOV_FLAG_FRAG_EVERY_FRAME  (1 << 20)
+#define FF_MOV_FLAG_SKIP_SIDX (1 << 21)
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v3] avformat/movenc: Added an option to disable SIDX atom

2018-12-05 Thread Karthick J
---
 doc/muxers.texi  |  4 
 libavformat/movenc.c | 12 ++--
 libavformat/movenc.h |  1 +
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index f1cc6f5fee..ca10741900 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1325,6 +1325,10 @@ more efficient), but with this option set, the muxer 
writes one moof/mdat
 pair for each track, making it easier to separate tracks.
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
+@item -movflags skip_sidx
+Skip writing of sidx atom. When bitrate overhead due to sidx atom is high,
+this option could be used for cases where sidx atom is not mandatory.
+When global_sidx flag is enabled, this option will be ignored. 
 @item -movflags faststart
 Run a second pass moving the index (moov atom) to the beginning of the file.
 This operation can take a while, and will not work in various situations such
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6dab5193b0..2f7755bf69 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -75,6 +75,7 @@ static const AVOption options[] = {
 { "frag_discont", "Signal that the next fragment is discontinuous from 
earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, 
INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
 { "delay_moov", "Delay writing the initial moov until the first fragment 
is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "global_sidx", "Write a global sidx index at the start of the file", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+{ "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_colr", "Write colr atom (Experimental, may be renamed or changed, 
do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 
= FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "use_metadata_tags", "Use mdta atom for metadata.", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
@@ -4603,7 +4604,8 @@ static int mov_write_moof_tag(AVIOContext *pb, 
MOVMuxContext *mov, int tracks,
 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
 moof_size = ffio_close_null_buf(avio_buf);
 
-if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX))
+if (mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | FF_MOV_FLAG_SKIP_SIDX)))
 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
 
 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
@@ -5422,7 +5424,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * the next fragment. This means the cts of the first sample must
  * be the same in all fragments, unless end_pts was updated by
  * the packet causing the fragment to be written. */
-if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX)) ||
+if ((mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | 
FF_MOV_FLAG_SKIP_SIDX))) ||
 mov->mode == MODE_ISM)
 pkt->pts = pkt->dts + trk->end_pts - 
trk->cluster[trk->entry].dts;
 } else {
@@ -6067,6 +6070,11 @@ static int mov_init(AVFormatContext *s)
 s->flags &= ~AVFMT_FLAG_AUTO_BSF;
 }
 
+if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX && s->flags & 
FF_MOV_FLAG_SKIP_SIDX) {
+av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx 
option\n");
+mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
+}
+
 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
 mov->reserved_moov_size = -1;
 }
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index fe605d1ad2..68d6f23a5a 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -257,6 +257,7 @@ typedef struct MOVMuxContext {
 #define FF_MOV_FLAG_SKIP_TRAILER  (1 << 18)
 #define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS  (1 << 19)
 #define FF_MOV_FLAG_FRAG_EVERY_FRAME  (1 << 20)
+#define FF_MOV_FLAG_SKIP_SIDX (1 << 21)
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/movenc: Added an option to disable SIDX atom

2018-12-04 Thread Karthick J
---
 doc/muxers.texi  |  4 
 libavformat/movenc.c | 12 ++--
 libavformat/movenc.h |  1 +
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index f1cc6f5fee..ca10741900 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1325,6 +1325,10 @@ more efficient), but with this option set, the muxer 
writes one moof/mdat
 pair for each track, making it easier to separate tracks.
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
+@item -movflags skip_sidx
+Skip writing of sidx atom. When bitrate overhead due to sidx atom is high,
+this option could be used for cases where sidx atom is not mandatory.
+When global_sidx flag is enabled, this option will be ignored. 
 @item -movflags faststart
 Run a second pass moving the index (moov atom) to the beginning of the file.
 This operation can take a while, and will not work in various situations such
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6dab5193b0..3781a32895 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -75,6 +75,7 @@ static const AVOption options[] = {
 { "frag_discont", "Signal that the next fragment is discontinuous from 
earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, 
INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
 { "delay_moov", "Delay writing the initial moov until the first fragment 
is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "global_sidx", "Write a global sidx index at the start of the file", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+{ "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_colr", "Write colr atom (Experimental, may be renamed or changed, 
do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 
= FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "use_metadata_tags", "Use mdta atom for metadata.", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
@@ -4603,7 +4604,8 @@ static int mov_write_moof_tag(AVIOContext *pb, 
MOVMuxContext *mov, int tracks,
 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
 moof_size = ffio_close_null_buf(avio_buf);
 
-if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX))
+if (mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | FF_MOV_FLAG_SKIP_SIDX)))
 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
 
 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
@@ -5422,7 +5424,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * the next fragment. This means the cts of the first sample must
  * be the same in all fragments, unless end_pts was updated by
  * the packet causing the fragment to be written. */
-if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX)) ||
+if ((mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | 
FF_MOV_FLAG_SKIP_SIDX))) ||
 mov->mode == MODE_ISM)
 pkt->pts = pkt->dts + trk->end_pts - 
trk->cluster[trk->entry].dts;
 } else {
@@ -6067,6 +6070,11 @@ static int mov_init(AVFormatContext *s)
 s->flags &= ~AVFMT_FLAG_AUTO_BSF;
 }
 
+if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX && s->flags & 
FF_MOV_FLAG_SKIP_SIDX) {
+av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx 
option\n");
+s->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
+}
+
 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
 mov->reserved_moov_size = -1;
 }
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index fe605d1ad2..68d6f23a5a 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -257,6 +257,7 @@ typedef struct MOVMuxContext {
 #define FF_MOV_FLAG_SKIP_TRAILER  (1 << 18)
 #define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS  (1 << 19)
 #define FF_MOV_FLAG_FRAG_EVERY_FRAME  (1 << 20)
+#define FF_MOV_FLAG_SKIP_SIDX (1 << 21)
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Used the movenc option skip_sidx instead of global_sidx

2018-12-04 Thread Karthick J
Anyways the intended behaviour was to disable SIDX atom.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 4d9b564a94..585b34cb97 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1162,7 +1162,7 @@ static int dash_init(AVFormatContext *s)
 
 if (os->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
-av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+global_sidx", 0);
+av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+skip_sidx", 0);
 else
 av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
 } else {
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 1/2] avformat/movenc: Added an option to disable SIDX atom

2018-12-04 Thread Karthick J
---
 doc/muxers.texi  | 2 ++
 libavformat/movenc.c | 7 +--
 libavformat/movenc.h | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index f1cc6f5fee..6ca27b04a3 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1325,6 +1325,8 @@ more efficient), but with this option set, the muxer 
writes one moof/mdat
 pair for each track, making it easier to separate tracks.
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
+@item -movflags no_sidx
+Don't write sidx atom.
 @item -movflags faststart
 Run a second pass moving the index (moov atom) to the beginning of the file.
 This operation can take a while, and will not work in various situations such
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6dab5193b0..83278e8bfd 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -75,6 +75,7 @@ static const AVOption options[] = {
 { "frag_discont", "Signal that the next fragment is discontinuous from 
earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, 
INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
 { "delay_moov", "Delay writing the initial moov until the first fragment 
is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "global_sidx", "Write a global sidx index at the start of the file", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+{ "no_sidx", "Don't write sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_NO_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" 
},
 { "write_colr", "Write colr atom (Experimental, may be renamed or changed, 
do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = 
FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 
= FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 
"movflags" },
 { "use_metadata_tags", "Use mdta atom for metadata.", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
@@ -4603,7 +4604,8 @@ static int mov_write_moof_tag(AVIOContext *pb, 
MOVMuxContext *mov, int tracks,
 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
 moof_size = ffio_close_null_buf(avio_buf);
 
-if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX))
+if (mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | FF_MOV_FLAG_NO_SIDX)))
 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
 
 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
@@ -5422,7 +5424,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * the next fragment. This means the cts of the first sample must
  * be the same in all fragments, unless end_pts was updated by
  * the packet causing the fragment to be written. */
-if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & 
FF_MOV_FLAG_GLOBAL_SIDX)) ||
+if ((mov->flags & FF_MOV_FLAG_DASH &&
+!(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | 
FF_MOV_FLAG_NO_SIDX))) ||
 mov->mode == MODE_ISM)
 pkt->pts = pkt->dts + trk->end_pts - 
trk->cluster[trk->entry].dts;
 } else {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index fe605d1ad2..ee6749bce2 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -257,6 +257,7 @@ typedef struct MOVMuxContext {
 #define FF_MOV_FLAG_SKIP_TRAILER  (1 << 18)
 #define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS  (1 << 19)
 #define FF_MOV_FLAG_FRAG_EVERY_FRAME  (1 << 20)
+#define FF_MOV_FLAG_NO_SIDX   (1 << 21)
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Used the movenc option no_sidx instead of global_sidx

2018-12-04 Thread Karthick J
Anyways the intended behaviour was to disable SIDX atom.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 4d9b564a94..84bc58d6c1 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1162,7 +1162,7 @@ static int dash_init(AVFormatContext *s)
 
 if (os->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
-av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+global_sidx", 0);
+av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+no_sidx", 0);
 else
 av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
 } else {
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Added proper logging when io_open fails for write

2018-11-29 Thread Karthick J
---
 libavformat/dashenc.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 04218af6a6..09207dcf44 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -209,6 +209,15 @@ static const char *get_format_str(SegmentType 
segment_type) {
 return NULL;
 }
 
+static int handle_io_open_error(AVFormatContext *s, int err, char *url) {
+DASHContext *c = s->priv_data;
+char errbuf[AV_ERROR_MAX_STRING_SIZE];
+av_strerror(err, errbuf, sizeof(errbuf));
+av_log(s, c->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR,
+   "Unable to open %s for writing: %s\n", url, errbuf);
+return c->ignore_io_errors ? 0 : err;
+}
+
 static inline SegmentType select_segment_type(SegmentType segment_type, enum 
AVCodecID codec_id)
 {
 if (segment_type == SEGMENT_TYPE_AUTO) {
@@ -531,7 +540,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 ret = dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
 av_dict_free(_opts);
 if (ret < 0) {
-av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename_hls);
+handle_io_open_error(s, ret, temp_filename_hls);
 return;
 }
 for (i = start_index; i < os->nb_segments; i++) {
@@ -846,8 +855,7 @@ static int write_manifest(AVFormatContext *s, int final)
 ret = dashenc_io_open(s, >mpd_out, temp_filename, );
 av_dict_free();
 if (ret < 0) {
-av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
-return c->ignore_io_errors ? 0 : ret;
+return handle_io_open_error(s, ret, temp_filename);
 }
 out = c->mpd_out;
 avio_printf(out, "\n");
@@ -937,8 +945,7 @@ static int write_manifest(AVFormatContext *s, int final)
 ret = dashenc_io_open(s, >m3u8_out, temp_filename, );
 av_dict_free();
 if (ret < 0) {
-av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
-return c->ignore_io_errors ? 0 : ret;
+return handle_io_open_error(s, ret, temp_filename);
 }
 
 ff_hls_write_playlist_version(c->m3u8_out, 7);
@@ -1567,7 +1574,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 ret = dashenc_io_open(s, >out, os->temp_path, );
 av_dict_free();
 if (ret < 0) {
-return c->ignore_io_errors ? 0 : ret;
+return handle_io_open_error(s, ret, os->temp_path);
 }
 }
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Added an option to ignore io errors

2018-11-28 Thread Karthick J
When dashenc has to run for long duration(say 24x7 live stream), one can enable 
this option to ignore the io failure of few segment's upload due to an 
intermittent network issues.
When the network connection recovers dashenc will continue with the upload of 
the current segments, leading to the recovery of the stream.
---
 doc/muxers.texi   |  3 +++
 libavformat/dashenc.c | 17 +++--
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index a02ac01b55..f1cc6f5fee 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -300,6 +300,9 @@ If this flag is set, the dash segment files will be in in 
ISOBMFF format.
 @item webm
 If this flag is set, the dash segment files will be in in WebM format.
 
+@item -ignore_io_errors @var{ignore_io_errors}
+Ignore IO errors during open and write. Useful for long-duration runs with 
network output.
+
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 2f403257c0..04218af6a6 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -138,6 +138,7 @@ typedef struct DASHContext {
 int index_correction;
 char *format_options_str;
 SegmentType segment_type_option;  /* segment type as specified in options 
*/
+int ignore_io_errors;
 } DASHContext;
 
 static struct codec_string {
@@ -846,7 +847,7 @@ static int write_manifest(AVFormatContext *s, int final)
 av_dict_free();
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
-return ret;
+return c->ignore_io_errors ? 0 : ret;
 }
 out = c->mpd_out;
 avio_printf(out, "\n");
@@ -937,7 +938,7 @@ static int write_manifest(AVFormatContext *s, int final)
 av_dict_free();
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
-return ret;
+return c->ignore_io_errors ? 0 : ret;
 }
 
 ff_hls_write_playlist_version(c->m3u8_out, 7);
@@ -1565,8 +1566,9 @@ static int dash_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 set_http_options(, c);
 ret = dashenc_io_open(s, >out, os->temp_path, );
 av_dict_free();
-if (ret < 0)
-return ret;
+if (ret < 0) {
+return c->ignore_io_errors ? 0 : ret;
+}
 }
 
 //write out the data immediately in streaming mode
@@ -1577,9 +1579,11 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 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);
+if (os->out) {
+avio_write(os->out, buf + os->written_len, len - os->written_len);
+avio_flush(os->out);
+}
 os->written_len = len;
-avio_flush(os->out);
 }
 
 return ret;
@@ -1670,6 +1674,7 @@ static const AVOption options[] = {
 { "auto", "select segment file format based on codec", 0, 
AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_AUTO }, 0, UINT_MAX,   E, 
"segment_type"},
 { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, 
{.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX,   E, "segment_type"},
 { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 
= SEGMENT_TYPE_WEBM }, 0, UINT_MAX,   E, "segment_type"},
+{ "ignore_io_errors", "Ignore IO errors during open and write. Useful for 
long-duration runs with network output", OFFSET(ignore_io_errors), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
 { NULL },
 };
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/dashenc: Handled the error from dashenc_io_open()

2018-11-28 Thread Karthick J
---
 libavformat/dashenc.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 6ce70e0076..2f403257c0 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -527,8 +527,12 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
 
 set_http_options(_opts, c);
-dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
+ret = dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
 av_dict_free(_opts);
+if (ret < 0) {
+av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename_hls);
+return;
+}
 for (i = start_index; i < os->nb_segments; i++) {
 Segment *seg = os->segments[i];
 double duration = (double) seg->duration / timescale;
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2] avformat/movenc : Don't write sidx for empty urls

2018-11-28 Thread Karthick J
When movenc is used by other segmenting muxers such as dashenc, url field is 
always empty.
In such cases it is better to not write sidx, instead of throwing errors.
---
 libavformat/movenc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6dab5193b0..d47ecc65ca 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -6706,6 +6706,9 @@ static int mov_write_trailer(AVFormatContext *s)
mov->tracks[i].data_offset = 0;
 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
 int64_t end;
+// If url is an empty string("") don't write sidx atom.
+if (s->url[0] == '\0')
+return 0;
 av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx 
atoms\n");
 res = shift_data(s);
 if (res < 0)
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/movenc : Don't write sidx for empty urls

2018-11-28 Thread Karthick J
When movenc is used by other segmenting muxers such as dashenc, url field is 
always empty.
In such cases it is better to not write sidx, instead of throwing errors.
---
 libavformat/movenc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6dab5193b0..150a505a4a 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -6706,6 +6706,9 @@ static int mov_write_trailer(AVFormatContext *s)
mov->tracks[i].data_offset = 0;
 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
 int64_t end;
+// If url is an empty string("") don't write sidx atom.
+if (s->url[0] == '\0')
+return res;
 av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx 
atoms\n");
 res = shift_data(s);
 if (res < 0)
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Added an option to ignore io errors

2018-11-26 Thread Karthick J
When dashenc has to run for long duration(say 24x7 live stream), one can enable 
this option to ignore the io failure of few segment's upload due to an 
intermittent network issues.
When the network connection recovers dashenc will continue with the upload of 
the current segments, leading to the recovery of the stream.
---
 doc/muxers.texi   |  3 +++
 libavformat/dashenc.c | 26 --
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index a02ac01b55..f1cc6f5fee 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -300,6 +300,9 @@ If this flag is set, the dash segment files will be in in 
ISOBMFF format.
 @item webm
 If this flag is set, the dash segment files will be in in WebM format.
 
+@item -ignore_io_errors @var{ignore_io_errors}
+Ignore IO errors during open and write. Useful for long-duration runs with 
network output.
+
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 2f403257c0..92b09417df 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -138,6 +138,7 @@ typedef struct DASHContext {
 int index_correction;
 char *format_options_str;
 SegmentType segment_type_option;  /* segment type as specified in options 
*/
+int ignore_io_errors;
 } DASHContext;
 
 static struct codec_string {
@@ -846,7 +847,10 @@ static int write_manifest(AVFormatContext *s, int final)
 av_dict_free();
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
-return ret;
+if (c->ignore_io_errors)
+return 0;
+else
+return ret;
 }
 out = c->mpd_out;
 avio_printf(out, "\n");
@@ -937,7 +941,10 @@ static int write_manifest(AVFormatContext *s, int final)
 av_dict_free();
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
-return ret;
+if (c->ignore_io_errors)
+return 0;
+else
+return ret;
 }
 
 ff_hls_write_playlist_version(c->m3u8_out, 7);
@@ -1565,8 +1572,12 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 set_http_options(, c);
 ret = dashenc_io_open(s, >out, os->temp_path, );
 av_dict_free();
-if (ret < 0)
-return ret;
+if (ret < 0) {
+if (c->ignore_io_errors)
+return 0;
+else
+return ret;
+}
 }
 
 //write out the data immediately in streaming mode
@@ -1577,9 +1588,11 @@ static int dash_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 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);
+if (os->out) {
+avio_write(os->out, buf + os->written_len, len - os->written_len);
+avio_flush(os->out);
+}
 os->written_len = len;
-avio_flush(os->out);
 }
 
 return ret;
@@ -1670,6 +1683,7 @@ static const AVOption options[] = {
 { "auto", "select segment file format based on codec", 0, 
AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_AUTO }, 0, UINT_MAX,   E, 
"segment_type"},
 { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, 
{.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX,   E, "segment_type"},
 { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 
= SEGMENT_TYPE_WEBM }, 0, UINT_MAX,   E, "segment_type"},
+{ "ignore_io_errors", "Ignore IO errors during open and write. Useful for 
long-duration runs with network output", OFFSET(ignore_io_errors), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
 { NULL },
 };
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Handled the error from dashenc_io_open()

2018-11-26 Thread Karthick J
---
 libavformat/dashenc.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 6ce70e0076..2f403257c0 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -527,8 +527,12 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, AVFormatCont
 snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
 
 set_http_options(_opts, c);
-dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
+ret = dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
 av_dict_free(_opts);
+if (ret < 0) {
+av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename_hls);
+return;
+}
 for (i = start_index; i < os->nb_segments; i++) {
 Segment *seg = os->segments[i];
 double duration = (double) seg->duration / timescale;
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc : Handled error from ff_http_do_new_request() cleanly

2018-11-16 Thread Karthick J
---
 libavformat/dashenc.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index d151921175..2c1cce0c92 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -168,6 +168,8 @@ static int dashenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 URLContext *http_url_context = ffio_geturlcontext(*pb);
 av_assert0(http_url_context);
 err = ff_http_do_new_request(http_url_context, filename);
+if (err < 0)
+ff_format_io_close(s, pb);
 #endif
 }
 return err;
@@ -177,6 +179,9 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 DASHContext *c = s->priv_data;
 int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
 
+if (!*pb)
+return;
+
 if (!http_base_proto || !c->http_persistent) {
 ff_format_io_close(s, pb);
 #if CONFIG_HTTP_PROTOCOL
@@ -318,7 +323,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 + os->written_len, *range_length - 
os->written_len);
+if (os->out)
+avio_write(os->out, buffer + os->written_len, *range_length - 
os->written_len);
 os->written_len = 0;
 av_free(buffer);
 
@@ -1496,9 +1502,9 @@ static int dash_write_packet(AVFormatContext *s, AVPacket 
*pkt)
  use_rename ? "%s.tmp" : "%s", os->full_path);
 set_http_options(, c);
 ret = dashenc_io_open(s, >out, os->temp_path, );
+av_dict_free();
 if (ret < 0)
 return ret;
-av_dict_free();
 }
 
 //write out the data immediately in streaming mode
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH 2/2] avformat/http : Added check for valid URL context before calling shutdown

2018-11-16 Thread Karthick J
---
 libavformat/http.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 3a35bc7eac..240304f6e6 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1650,7 +1650,7 @@ static int http_close(URLContext *h)
 av_freep(>inflate_buffer);
 #endif /* CONFIG_ZLIB */
 
-if (!s->end_chunked_post)
+if (s->hd && !s->end_chunked_post)
 /* Close the write direction by sending the end of chunked encoding. */
 ret = http_shutdown(h, h->flags);
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Disable writing CODECS tag for HEVC streams

2018-10-21 Thread Karthick J
For HEVC streams, only the FourCC tag is written without profile, level etc.,
This is breaking playout support in native Safari.
Native Safari playout expects the full info in CODECS tag or None at all.
---
 libavformat/dashenc.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 4e2ea2ebf2..f8b3d106d5 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -915,6 +915,7 @@ static int write_manifest(AVFormatContext *s, int final)
 AVStream *st = s->streams[i];
 OutputStream *os = >streams[i];
 char *agroup = NULL;
+char *codec_str_ptr = NULL;
 int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead;
 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
 continue;
@@ -925,10 +926,13 @@ static int write_manifest(AVFormatContext *s, int final)
 av_strlcat(codec_str, ",", sizeof(codec_str));
 av_strlcat(codec_str, audio_codec_str, sizeof(codec_str));
 }
+if (st->codecpar->codec_id != AV_CODEC_ID_HEVC) {
+codec_str_ptr = codec_str;
+}
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
 ff_hls_write_stream_info(st, c->m3u8_out, stream_bitrate,
  playlist_file, agroup,
- codec_str, NULL);
+ codec_str_ptr, NULL);
 }
 dashenc_io_close(s, >m3u8_out, temp_filename);
 if (use_rename)
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Support HTTP persistent for init segments as well

2018-10-20 Thread Karthick J
---
 libavformat/dashenc.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index b0a59af3ee..4e2ea2ebf2 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -355,8 +355,11 @@ static int flush_init_segment(AVFormatContext *s, 
OutputStream *os)
 return ret;
 
 os->pos = os->init_range_length = range_length;
-if (!c->single_file)
-ff_format_io_close(s, >out);
+if (!c->single_file) {
+char filename[1024];
+snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
+dashenc_io_close(s, >out, filename);
+}
 return 0;
 }
 
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: URL close unconditionally after DELETE segments

2018-10-18 Thread Karthick J
Fixes bug with HTTP DELETE when HTTP Persistent is ON.
Right now, HTTP Persistent connections is supported only for POSTs and PUTs.
HTTP DELETE will still open a new connection every time.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 15b84a0f3b..b0a59af3ee 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1253,7 +1253,7 @@ static void dashenc_delete_file(AVFormatContext *s, char 
*filename) {
 }
 
 av_dict_free(_opts);
-dashenc_io_close(s, , filename);
+ff_format_io_close(s, );
 } else if (unlink(filename) < 0) {
 av_log(s, AV_LOG_ERROR, "failed to delete %s: %s\n", filename, 
strerror(errno));
 }
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Support HTTP Persistent for master.mu8 as well

2018-10-18 Thread Karthick J
---
 libavformat/dashenc.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 3f5f290e25..15b84a0f3b 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -878,14 +878,14 @@ static int write_manifest(AVFormatContext *s, int final)
 snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : 
"%s", filename_hls);
 
 set_http_options(, c);
-ret = avio_open2(, temp_filename, AVIO_FLAG_WRITE, NULL, );
+ret = dashenc_io_open(s, >m3u8_out, temp_filename, );
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
 return ret;
 }
 av_dict_free();
 
-ff_hls_write_playlist_version(out, 7);
+ff_hls_write_playlist_version(c->m3u8_out, 7);
 
 for (i = 0; i < s->nb_streams; i++) {
 char playlist_file[64];
@@ -894,7 +894,7 @@ static int write_manifest(AVFormatContext *s, int final)
 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
 continue;
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_audio_rendition(out, (char *)audio_group,
+ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group,
  playlist_file, i, is_default);
 max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
   os->muxer_overhead, max_audio_bitrate);
@@ -923,10 +923,11 @@ static int write_manifest(AVFormatContext *s, int final)
 av_strlcat(codec_str, audio_codec_str, sizeof(codec_str));
 }
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup,
+ff_hls_write_stream_info(st, c->m3u8_out, stream_bitrate,
+ playlist_file, agroup,
  codec_str, NULL);
 }
-avio_close(out);
+dashenc_io_close(s, >m3u8_out, temp_filename);
 if (use_rename)
 if ((ret = avpriv_io_move(temp_filename, filename_hls)) < 0)
 return ret;
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2] avformat/dashenc: Support HTTP Persistent for master.m3u8 as well

2018-10-18 Thread Karthick J
---
 libavformat/dashenc.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 3f5f290e25..15b84a0f3b 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -878,14 +878,14 @@ static int write_manifest(AVFormatContext *s, int final)
 snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : 
"%s", filename_hls);
 
 set_http_options(, c);
-ret = avio_open2(, temp_filename, AVIO_FLAG_WRITE, NULL, );
+ret = dashenc_io_open(s, >m3u8_out, temp_filename, );
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
 return ret;
 }
 av_dict_free();
 
-ff_hls_write_playlist_version(out, 7);
+ff_hls_write_playlist_version(c->m3u8_out, 7);
 
 for (i = 0; i < s->nb_streams; i++) {
 char playlist_file[64];
@@ -894,7 +894,7 @@ static int write_manifest(AVFormatContext *s, int final)
 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
 continue;
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_audio_rendition(out, (char *)audio_group,
+ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group,
  playlist_file, i, is_default);
 max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
   os->muxer_overhead, max_audio_bitrate);
@@ -923,10 +923,11 @@ static int write_manifest(AVFormatContext *s, int final)
 av_strlcat(codec_str, audio_codec_str, sizeof(codec_str));
 }
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup,
+ff_hls_write_stream_info(st, c->m3u8_out, stream_bitrate,
+ playlist_file, agroup,
  codec_str, NULL);
 }
-avio_close(out);
+dashenc_io_close(s, >m3u8_out, temp_filename);
 if (use_rename)
 if ((ret = avpriv_io_move(temp_filename, filename_hls)) < 0)
 return ret;
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Support HTTP Persistent for master.mu8 as well

2018-10-18 Thread Karthick J
---
 libavformat/dashenc.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 3f5f290e25..15b84a0f3b 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -878,14 +878,14 @@ static int write_manifest(AVFormatContext *s, int final)
 snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : 
"%s", filename_hls);
 
 set_http_options(, c);
-ret = avio_open2(, temp_filename, AVIO_FLAG_WRITE, NULL, );
+ret = dashenc_io_open(s, >m3u8_out, temp_filename, );
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
 return ret;
 }
 av_dict_free();
 
-ff_hls_write_playlist_version(out, 7);
+ff_hls_write_playlist_version(c->m3u8_out, 7);
 
 for (i = 0; i < s->nb_streams; i++) {
 char playlist_file[64];
@@ -894,7 +894,7 @@ static int write_manifest(AVFormatContext *s, int final)
 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
 continue;
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_audio_rendition(out, (char *)audio_group,
+ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group,
  playlist_file, i, is_default);
 max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
   os->muxer_overhead, max_audio_bitrate);
@@ -923,10 +923,11 @@ static int write_manifest(AVFormatContext *s, int final)
 av_strlcat(codec_str, audio_codec_str, sizeof(codec_str));
 }
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup,
+ff_hls_write_stream_info(st, c->m3u8_out, stream_bitrate,
+ playlist_file, agroup,
  codec_str, NULL);
 }
-avio_close(out);
+dashenc_io_close(s, >m3u8_out, temp_filename);
 if (use_rename)
 if ((ret = avpriv_io_move(temp_filename, filename_hls)) < 0)
 return ret;
-- 
2.17.1 (Apple Git-112)

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


[FFmpeg-devel] [PATCH v2] avdevice/decklink: Add option to align Capture start time

2018-09-28 Thread Karthick J
From: Karthick Jeyapal 

This option is useful for maintaining input synchronization across N
different hardware devices deployed for 'N-way' redundancy.
The system time of different hardware devices should be synchronized
with protocols such as NTP or PTP, before using this option.
---
 doc/indevs.texi | 13 +
 libavdevice/decklink_common_c.h |  1 +
 libavdevice/decklink_dec.cpp| 11 +++
 libavdevice/decklink_dec_c.c|  1 +
 4 files changed, 26 insertions(+)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index ed2784b..694bac9 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -371,6 +371,19 @@ If set to @option{true}, timestamps are forwarded as they 
are without removing
 the initial offset.
 Defaults to @option{false}.
 
+@item timestamp_align
+Capture start time alignment in seconds. If set to nonzero, input frames are
+dropped till the system timestamp aligns with configured value.
+Alignment difference of upto one frame duration is tolerated.
+This is useful for maintaining input synchronization across N different
+hardware devices deployed for 'N-way' redundancy. The system time of different
+hardware devices should be synchronized with protocols such as NTP or PTP,
+before using this option.
+Note that this method not foolproof. In some border cases input synchronization
+may not happen due to thread scheduling jitters in the OS. Either sync could go
+wrong by 1 frame or in a rarer case by even @option{timestamp_align} seconds.
+Defaults to @samp{0}.
+
 @end table
 
 @subsection Examples
diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
index 32a5d70..8e3bbeb 100644
--- a/libavdevice/decklink_common_c.h
+++ b/libavdevice/decklink_common_c.h
@@ -56,6 +56,7 @@ struct decklink_cctx {
 int raw_format;
 int64_t queue_size;
 int copyts;
+int64_t timestamp_align;
 };
 
 #endif /* AVDEVICE_DECKLINK_COMMON_C_H */
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 7fabef2..1f4d68b 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -703,6 +703,17 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
 return S_OK;
 }
 
+// Drop the frames till system's timestamp aligns with the configured 
value.
+if (0 == ctx->frameCount && cctx->timestamp_align) {
+AVRational remainder = av_make_q(av_gettime() % cctx->timestamp_align, 
100);
+AVRational frame_duration = av_make_q(ctx->video_st->r_frame_rate.den,
+  ctx->video_st->r_frame_rate.num);
+if (av_cmp_q(remainder, frame_duration) > 0) {
+++ctx->dropped;
+return S_OK;
+}
+}
+
 ctx->frameCount++;
 if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == 
PTS_SRC_WALLCLOCK)
 wallclock = av_gettime_relative();
diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
index 6ab3819..2e6fcb6 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -84,6 +84,7 @@ static const AVOption options[] = {
 { "queue_size","input queue buffer size",   OFFSET(queue_size),   
AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
 { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),  
AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },
 { "decklink_copyts", "copy timestamps, do not remove the initial offset", 
OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC },
+{ "timestamp_align", "Capture start time alignment (in seconds)", 
OFFSET(timestamp_align), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, DEC },
 { NULL },
 };
 
-- 
2.7.4

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


[FFmpeg-devel] [PATCH] avdevice/decklink: Add option to align Capture start time

2018-09-24 Thread Karthick J
From: Karthick Jeyapal 

This option is useful for maintaining input synchronization across N
different hardware devices deployed for 'N-way' redundancy.
The system time of different hardware devices should be synchronized
with protocols such as NTP or PTP, before using this option.
---
 doc/indevs.texi | 10 ++
 libavdevice/decklink_common_c.h |  1 +
 libavdevice/decklink_dec.cpp| 20 
 libavdevice/decklink_dec_c.c|  1 +
 4 files changed, 32 insertions(+)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index ed2784b..dfd530a 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -371,6 +371,16 @@ If set to @option{true}, timestamps are forwarded as they 
are without removing
 the initial offset.
 Defaults to @option{false}.
 
+@item timestamp_align
+Capture start time alignment in seconds. If set to nonzero, input frames are
+dropped till the system timestamp aligns with configured value.
+Alignment difference of upto one frame duration is tolerated.
+This is useful for maintaining input synchronization across N different
+hardware devices deployed for 'N-way' redundancy. The system time of different
+hardware devices should be synchronized with protocols such as NTP or PTP,
+before using this option.
+Defaults to @samp{0}.
+
 @end table
 
 @subsection Examples
diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
index 32a5d70..c4a8985 100644
--- a/libavdevice/decklink_common_c.h
+++ b/libavdevice/decklink_common_c.h
@@ -56,6 +56,7 @@ struct decklink_cctx {
 int raw_format;
 int64_t queue_size;
 int copyts;
+int timestamp_align;
 };
 
 #endif /* AVDEVICE_DECKLINK_COMMON_C_H */
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 7fabef2..24f5ca9 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -703,6 +703,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
 return S_OK;
 }
 
+// Drop the frames till system's timestamp aligns with the configured 
value.
+if (0 == ctx->frameCount && cctx->timestamp_align) {
+int64_t current_time_us = av_gettime();
+int64_t align_factor_us = (cctx->timestamp_align * 100);
+int remainder = current_time_us % align_factor_us;
+if (videoFrame) {
+videoFrame->GetStreamTime(, , 100);
+} else if (audioFrame) {
+long sample_count = audioFrame->GetSampleFrameCount();
+frameDuration = (long)(sample_count * 100) / 
bmdAudioSampleRate48kHz;
+} else {
+frameDuration = 0;
+}
+// threshold of one frameDuration
+if(remainder > frameDuration) {
+++ctx->dropped;
+return S_OK;
+}
+}
+
 ctx->frameCount++;
 if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == 
PTS_SRC_WALLCLOCK)
 wallclock = av_gettime_relative();
diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
index 6ab3819..bef9c14 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -84,6 +84,7 @@ static const AVOption options[] = {
 { "queue_size","input queue buffer size",   OFFSET(queue_size),   
AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
 { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),  
AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },
 { "decklink_copyts", "copy timestamps, do not remove the initial offset", 
OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC },
+{ "timestamp_align", "Capture start time alignment (in seconds)", 
OFFSET(timestamp_align), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, DEC },
 { NULL },
 };
 
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/dashenc: Format VP9 level as decimal instead of hexadecimal

2018-09-17 Thread Karthick J
From: Karthick Jeyapal 

Commit ID 63c69d51c7532fb6c2460076329b50ec51a0f290 fixed the bug in vpcc, 
get_vp9_level() function, causing this change.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 9a33321..f429ebc 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -211,7 +211,7 @@ static void set_vp9_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
 VPCC vpcc;
 int ret = ff_isom_get_vpcc_features(s, par, frame_rate, );
 if (ret == 0) {
-av_strlcatf(str, size, "vp09.%02x.%02x.%02x",
+av_strlcatf(str, size, "vp09.%02x.%02d.%02x",
 vpcc.profile, vpcc.level, vpcc.bitdepth);
 } else {
 // Default to just vp9 in case of error while finding out profile or 
level
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Format VP9 bitdepth as decimal instead of Hexadecimal

2018-09-17 Thread Karthick J
From: Karthick Jeyapal 

For example bitdepth should be printed as 10 instead of 0A. Thanks to Hendrik 
Leppkes for pointing this out
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index f429ebc..1a201c3 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -211,7 +211,7 @@ static void set_vp9_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
 VPCC vpcc;
 int ret = ff_isom_get_vpcc_features(s, par, frame_rate, );
 if (ret == 0) {
-av_strlcatf(str, size, "vp09.%02x.%02d.%02x",
+av_strlcatf(str, size, "vp09.%02x.%02d.%02d",
 vpcc.profile, vpcc.level, vpcc.bitdepth);
 } else {
 // Default to just vp9 in case of error while finding out profile or 
level
-- 
2.7.4

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Format VP9 level as decimal instead of hexadecimal

2018-09-17 Thread Karthick J
From: Karthick Jeyapal 

Commit ID 63c69d51c7532fb6c2460076329b50ec51a0f290 fixed the bug in vpcc, 
get_vp9_level() function, causing this change.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 9a33321..f429ebc 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -211,7 +211,7 @@ static void set_vp9_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
 VPCC vpcc;
 int ret = ff_isom_get_vpcc_features(s, par, frame_rate, );
 if (ret == 0) {
-av_strlcatf(str, size, "vp09.%02x.%02x.%02x",
+av_strlcatf(str, size, "vp09.%02x.%02d.%02x",
 vpcc.profile, vpcc.level, vpcc.bitdepth);
 } else {
 // Default to just vp9 in case of error while finding out profile or 
level
-- 
2.7.4

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Reduce Muxing overhead for chunked CMAF format

2018-09-14 Thread Karthick J
From: Karthick Jeyapal 

SIDX atom being inserted for every MOOF atom increases the muxing overhead.
This behaviour can be disabled for chunked CMAF format by enabling Global SIDX 
option of mov muxer.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 87e31e2..9a33321 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1065,7 +1065,7 @@ static int dash_init(AVFormatContext *s)
 
 if (c->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
-av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov", 0);
+av_dict_set(, "movflags", 
"frag_every_frame+dash+delay_moov+global_sidx", 0);
 else
 av_dict_set(, "movflags", "frag_custom+dash+delay_moov", 
0);
 } else {
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/dashenc: Add CODECS tag to HLS master playlist

2018-09-04 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index ae57fd5..c36ab12 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -864,6 +864,7 @@ static int write_manifest(AVFormatContext *s, int final)
 if (c->hls_playlist && !c->master_playlist_created) {
 char filename_hls[1024];
 const char *audio_group = "A1";
+const char audio_codec_str[128] = "\0";
 int is_default = 1;
 int max_audio_bitrate = 0;
 
@@ -895,21 +896,31 @@ static int write_manifest(AVFormatContext *s, int final)
  playlist_file, i, is_default);
 max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
   os->muxer_overhead, max_audio_bitrate);
+if (!av_strnstr(audio_codec_str, os->codec_str, 
sizeof(audio_codec_str))) {
+if (strlen(audio_codec_str))
+av_strlcat(audio_codec_str, ",", sizeof(audio_codec_str));
+av_strlcat(audio_codec_str, os->codec_str, 
sizeof(audio_codec_str));
+}
 is_default = 0;
 }
 
 for (i = 0; i < s->nb_streams; i++) {
 char playlist_file[64];
+char codec_str[128];
 AVStream *st = s->streams[i];
 OutputStream *os = >streams[i];
 char *agroup = NULL;
 int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead;
+av_strlcpy(codec_str, os->codec_str, sizeof(codec_str));
 if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && 
max_audio_bitrate) {
 agroup = (char *)audio_group;
 stream_bitrate += max_audio_bitrate;
+av_strlcat(codec_str, ",", sizeof(codec_str));
+av_strlcat(codec_str, audio_codec_str, sizeof(codec_str));
 }
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup, NULL, NULL);
+ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup,
+ codec_str, NULL);
 }
 avio_close(out);
 if (use_rename)
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Remove muxer overhead from Bandwidth field in DASH manifest

2018-09-04 Thread Karthick J
From: Karthick Jeyapal 

Fixes bug id #7386
Muxer overhead calculations was intented for HLS playlist as Apple's 
mediastreamvalidator tests were failing.
But applying the same fix for DASH manifest proved counterproductive, as 
Bandwidth can be used for segment name templates.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index c36ab12..2564b9e 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -611,7 +611,7 @@ static int write_adaptation_set(AVFormatContext *s, 
AVIOContext *out, int as_ind
 
 if (os->bit_rate > 0)
 snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"",
- os->bit_rate + os->muxer_overhead);
+ os->bit_rate);
 
 if (as->media_type == AVMEDIA_TYPE_VIDEO) {
 AVStream *st = s->streams[i];
-- 
2.7.4

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Add CODECS tag to HLS master playlist

2018-08-21 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index ae57fd5..229a56e 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -909,7 +909,8 @@ static int write_manifest(AVFormatContext *s, int final)
 stream_bitrate += max_audio_bitrate;
 }
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup, NULL, NULL);
+ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup,
+ os->codec_str, NULL);
 }
 avio_close(out);
 if (use_rename)
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Added a warning for incorrect segment name extension

2018-05-14 Thread Karthick J
From: Karthick Jeyapal 

Applicable only to webm output format.
By default all the segment filenames end with .m4s extension.
When someone chooses webm output format, we recommend they also override the 
relevant segment name options to end with .webm extension. This patch will 
issue a warning for he same
---
 libavformat/dashenc.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 9a57ad1..4e83112 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -195,6 +195,16 @@ static const char *get_format_str(SegmentType 
segment_type) {
 return NULL;
 }
 
+static int check_file_extension(const char *filename, const char *extension) {
+char *dot;
+if (!filename || !extension)
+return -1;
+dot = strrchr(filename, '.');
+if (dot && !strcmp(dot + 1, extension))
+return 0;
+return -1;
+}
+
 static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par,
   AVRational *frame_rate, char *str, int size) {
 VPCC vpcc;
@@ -986,6 +996,17 @@ static int dash_init(AVFormatContext *s)
 c->format_name = get_format_str(c->segment_type);
 if (!c->format_name)
 return AVERROR_MUXER_NOT_FOUND;
+if (c->segment_type == SEGMENT_TYPE_WEBM) {
+if ((!c->single_file && check_file_extension(c->init_seg_name, 
c->format_name) != 0) ||
+(!c->single_file && check_file_extension(c->media_seg_name, 
c->format_name) != 0) ||
+(c->single_file && check_file_extension(c->single_file_name, 
c->format_name) != 0)) {
+av_log(s, AV_LOG_WARNING,
+   "One or many segment file names doesn't end with .webm. 
"
+   "Override -init_seg_name and/or -media_seg_name and/or "
+   "-single_file_name to end with the extension .webm\n");
+}
+}
+
 ctx->oformat = av_guess_format(c->format_name, NULL, NULL);
 if (!ctx->oformat)
 return AVERROR_MUXER_NOT_FOUND;
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/dashenc: Added option for Segment file format

2018-05-14 Thread Karthick J
From: Karthick Jeyapal 

Right now segment file format is chosen to be either mp4 or webm based on the 
codec format.
This patch makes that choice configurable by the user, instead of being decided 
by the muxer.

Also with this change per-stream choice segment file format(based on codec 
type) is not possible.
All the output audio and video streams should be in the same file format.
---
 doc/muxers.texi   |  8 +++
 libavformat/dashenc.c | 66 +--
 2 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 57948cf..ea80296 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -284,6 +284,14 @@ corrects that index value.
 Typically this logic is needed in live streaming use cases. The network 
bandwidth
 fluctuations are common during long run streaming. Each fluctuation can cause
 the segment indexes fall behind the expected real time position.
+
+@item dash_segment_type @var{dash_segment_type}
+Possible values:
+@item mp4
+If this flag is set, the dash segment files will be in in ISOBMFF format. This 
is the default format.
+
+@item webm
+If this flag is set, the dash segment files will be in in WebM format.
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 1dd6333..9a57ad1 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -48,6 +48,12 @@
 #include "vpcc.h"
 #include "dash.h"
 
+typedef enum {
+SEGMENT_TYPE_MP4 = 0,
+SEGMENT_TYPE_WEBM,
+SEGMENT_TYPE_NB
+} SegmentType;
+
 typedef struct Segment {
 char file[1024];
 int64_t start_pos;
@@ -69,7 +75,6 @@ typedef struct OutputStream {
 AVFormatContext *ctx;
 int ctx_inited, as_idx;
 AVIOContext *out;
-char format_name[8];
 int packets_written;
 char initfile[1024];
 int64_t init_start_pos, pos;
@@ -125,6 +130,8 @@ typedef struct DASHContext {
 int streaming;
 int64_t timeout;
 int index_correction;
+SegmentType segment_type;
+const char *format_name;
 } DASHContext;
 
 static struct codec_string {
@@ -138,6 +145,15 @@ static struct codec_string {
 { 0, NULL }
 };
 
+static struct format_string {
+SegmentType segment_type;
+const char *str;
+} formats[] = {
+{ SEGMENT_TYPE_MP4, "mp4" },
+{ SEGMENT_TYPE_WEBM, "webm" },
+{ 0, NULL }
+};
+
 static int dashenc_io_open(AVFormatContext *s, AVIOContext **pb, char 
*filename,
AVDictionary **options) {
 DASHContext *c = s->priv_data;
@@ -171,6 +187,14 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 }
 }
 
+static const char *get_format_str(SegmentType segment_type) {
+int i;
+for (i = 0; i < SEGMENT_TYPE_NB; i++)
+if (formats[i].segment_type == segment_type)
+return formats[i].str;
+return NULL;
+}
+
 static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par,
   AVRational *frame_rate, char *str, int size) {
 VPCC vpcc;
@@ -581,13 +605,13 @@ static int write_adaptation_set(AVFormatContext *s, 
AVIOContext *out, int as_ind
 if (as->media_type == AVMEDIA_TYPE_VIDEO) {
 AVStream *st = s->streams[i];
 avio_printf(out, "\t\t\tformat_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
+i, c->format_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
 if (st->avg_frame_rate.num)
 avio_printf(out, " frameRate=\"%d/%d\"", 
st->avg_frame_rate.num, st->avg_frame_rate.den);
 avio_printf(out, ">\n");
 } else {
 avio_printf(out, "\t\t\t\n",
-i, os->format_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->sample_rate);
+i, c->format_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->sample_rate);
 avio_printf(out, "\t\t\t\t\n",
 s->streams[i]->codecpar->channels);
 }
@@ -959,27 +983,10 @@ static int dash_init(AVFormatContext *s)
 if (!ctx)
 return AVERROR(ENOMEM);
 
-// choose muxer based on codec: webm for VP8 and opus, mp4 otherwise
-// note: os->format_name is also used as part of the mimetype of the
-//   representation, e.g. video/
-if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
-s->streams[i]->codecpar->codec_id == AV_CODEC_ID_OPUS ||
-s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VORBIS) {
-snprintf(os->format_name, sizeof(os->format_name), "webm");
-
-if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
-av_log(s, AV_LOG_ERROR,
-   "WebM support in dashenc is experimental and has not "
-   "been validated. For testing purposes, 

[FFmpeg-devel] [PATCH] avformat/dashenc: Add documentation for http method option

2018-05-06 Thread Karthick J
From: Karthick Jeyapal 

---
 doc/muxers.texi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 2429f8e..ea80296 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -252,6 +252,8 @@ DASH-templated name to used for the initialization segment. 
Default is "init-str
 DASH-templated name to used for the media segments. Default is 
"chunk-stream$RepresentationID$-$Number%05d$.m4s"
 @item -utc_timing_url @var{utc_url}
 URL of the page that will return the UTC timestamp in ISO format. Example: 
"https://time.akamai.com/?iso;
+@item method @var{method}
+Use the given HTTP method to create output files. Generally set to PUT or POST.
 @item -http_user_agent @var{user_agent}
 Override User-Agent field in HTTP header. Applicable only for HTTP output.
 @item -http_persistent @var{http_persistent}
-- 
2.7.4

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Added option for Segment file format

2018-05-04 Thread Karthick J
From: Karthick Jeyapal 

Right now segment file format is chosen to be either mp4 or webm based on the 
codec format.
This patch makes that choice configurable by the user, instead of being decided 
by the muxer.
---
 doc/muxers.texi   |  8 
 libavformat/dashenc.c | 48 ++--
 2 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 6f03bba..2429f8e 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -282,6 +282,14 @@ corrects that index value.
 Typically this logic is needed in live streaming use cases. The network 
bandwidth
 fluctuations are common during long run streaming. Each fluctuation can cause
 the segment indexes fall behind the expected real time position.
+
+@item dash_segment_type @var{dash_segment_type}
+Possible values:
+@item mp4
+If this flag is set, the dash segment files will be in in ISOBMFF format. This 
is the default format.
+
+@item webm
+If this flag is set, the dash segment files will be in in WebM format.
 @end table
 
 @anchor{framecrc}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 1dd6333..412f074 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -48,6 +48,11 @@
 #include "vpcc.h"
 #include "dash.h"
 
+typedef enum {
+SEGMENT_TYPE_MP4,
+SEGMENT_TYPE_WEBM,
+} SegmentType;
+
 typedef struct Segment {
 char file[1024];
 int64_t start_pos;
@@ -69,7 +74,6 @@ typedef struct OutputStream {
 AVFormatContext *ctx;
 int ctx_inited, as_idx;
 AVIOContext *out;
-char format_name[8];
 int packets_written;
 char initfile[1024];
 int64_t init_start_pos, pos;
@@ -125,6 +129,8 @@ typedef struct DASHContext {
 int streaming;
 int64_t timeout;
 int index_correction;
+SegmentType segment_type;
+char format_name[8];
 } DASHContext;
 
 static struct codec_string {
@@ -581,13 +587,13 @@ static int write_adaptation_set(AVFormatContext *s, 
AVIOContext *out, int as_ind
 if (as->media_type == AVMEDIA_TYPE_VIDEO) {
 AVStream *st = s->streams[i];
 avio_printf(out, "\t\t\tformat_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
+i, c->format_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
 if (st->avg_frame_rate.num)
 avio_printf(out, " frameRate=\"%d/%d\"", 
st->avg_frame_rate.num, st->avg_frame_rate.den);
 avio_printf(out, ">\n");
 } else {
 avio_printf(out, "\t\t\t\n",
-i, os->format_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->sample_rate);
+i, c->format_name, os->codec_str, bandwidth_str, 
s->streams[i]->codecpar->sample_rate);
 avio_printf(out, "\t\t\t\t\n",
 s->streams[i]->codecpar->channels);
 }
@@ -959,27 +965,14 @@ static int dash_init(AVFormatContext *s)
 if (!ctx)
 return AVERROR(ENOMEM);
 
-// choose muxer based on codec: webm for VP8 and opus, mp4 otherwise
-// note: os->format_name is also used as part of the mimetype of the
-//   representation, e.g. video/
-if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
-s->streams[i]->codecpar->codec_id == AV_CODEC_ID_OPUS ||
-s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VORBIS) {
-snprintf(os->format_name, sizeof(os->format_name), "webm");
-
-if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
-av_log(s, AV_LOG_ERROR,
-   "WebM support in dashenc is experimental and has not "
-   "been validated. For testing purposes, make sure "
-   "to add -strict experimental and override "
-   "-init_seg_name and -media_seg_name to end with "
-   "the extension 'webm'.\n");
-return AVERROR(EINVAL);
-}
+if (c->segment_type == SEGMENT_TYPE_WEBM) {
+snprintf(c->format_name, sizeof(c->format_name), "webm");
+} else if (c->segment_type == SEGMENT_TYPE_MP4) {
+snprintf(c->format_name, sizeof(c->format_name), "mp4");
 } else {
-snprintf(os->format_name, sizeof(os->format_name), "mp4");
+return AVERROR_MUXER_NOT_FOUND;
 }
-ctx->oformat = av_guess_format(os->format_name, NULL, NULL);
+ctx->oformat = av_guess_format(c->format_name, NULL, NULL);
 if (!ctx->oformat)
 return AVERROR_MUXER_NOT_FOUND;
 os->ctx = ctx;
@@ -1017,7 +1010,7 @@ static int dash_init(AVFormatContext *s)
 av_dict_free();
 os->init_start_pos = 0;
 
-if (!strcmp(os->format_name, "mp4")) {
+if (c->segment_type == SEGMENT_TYPE_MP4) {
 if (c->streaming)
 

[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Added a warning for incorrect segment name extension

2018-05-04 Thread Karthick J
From: Karthick Jeyapal 

Applicable only to webm output format.
By default all the segment filenames end with .m4s extension.
When someone chooses webm output format, we recommend they also override the 
relevant segment name options to end with .webm extension. This patch will 
issue a warning for he same.
---
 libavformat/dashenc.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 412f074..bd374e2 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -177,6 +177,16 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 }
 }
 
+static int check_file_extension(const char *filename, const char *extension) {
+char *dot;
+if (!filename || !extension)
+return -1;
+dot = strrchr(filename, '.');
+if (dot && !strcmp(dot + 1, extension))
+return 0;
+return -1;
+}
+
 static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par,
   AVRational *frame_rate, char *str, int size) {
 VPCC vpcc;
@@ -967,6 +977,14 @@ static int dash_init(AVFormatContext *s)
 
 if (c->segment_type == SEGMENT_TYPE_WEBM) {
 snprintf(c->format_name, sizeof(c->format_name), "webm");
+if ((!c->single_file && check_file_extension(c->init_seg_name, 
c->format_name) != 0) ||
+(!c->single_file && check_file_extension(c->media_seg_name, 
c->format_name) != 0) ||
+(c->single_file && check_file_extension(c->single_file_name, 
c->format_name) != 0)) {
+av_log(s, AV_LOG_WARNING,
+   "One or many segment file names doesn't end with .webm. 
"
+   "Override -init_seg_name and/or -media_seg_name and/or "
+   "-single_file_name to end with the extension .webm\n");
+}
 } else if (c->segment_type == SEGMENT_TYPE_MP4) {
 snprintf(c->format_name, sizeof(c->format_name), "mp4");
 } else {
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 3/3] avformat/dashenc: Set mp4 as the default format for VP9

2018-04-23 Thread Karthick J
From: Karthick Jeyapal 

There is a separate muxer(webmdashenc.c) for supporting VP9+webm output in DASH.
Hence in this muxer we will focus on supporting VP9 in MP4
Have verified playout support of VP9+MP4 in Chrome and Firefox.
---
 libavformat/dashenc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index a5f58d4..211ef23 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -959,11 +959,10 @@ static int dash_init(AVFormatContext *s)
 if (!ctx)
 return AVERROR(ENOMEM);
 
-// choose muxer based on codec: webm for VP8/9 and opus, mp4 otherwise
+// choose muxer based on codec: webm for VP8 and opus, mp4 otherwise
 // note: os->format_name is also used as part of the mimetype of the
 //   representation, e.g. video/
 if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
-s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP9 ||
 s->streams[i]->codecpar->codec_id == AV_CODEC_ID_OPUS ||
 s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VORBIS) {
 snprintf(os->format_name, sizeof(os->format_name), "webm");
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 1/3] avformat/vpcc: Calculate VP9 level from Luma's Sample rate and Picture size

2018-04-23 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/vpcc.c | 53 ++---
 libavformat/vpcc.h |  2 +-
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/libavformat/vpcc.c b/libavformat/vpcc.c
index 66d0df6..7951448 100644
--- a/libavformat/vpcc.c
+++ b/libavformat/vpcc.c
@@ -67,11 +67,58 @@ static int get_vpx_video_full_range_flag(enum AVColorRange 
color_range)
 return color_range == AVCOL_RANGE_JPEG;
 }
 
+// Find approximate VP9 level based on the Luma's Sample rate and Picture size.
+static int get_vp9_level(AVCodecParameters *par, AVRational *frame_rate) {
+int picture_size = par->width * par->height;
+int64_t sample_rate;
+
+// All decisions will be based on picture_size, if frame rate is 
missing/invalid
+if (!frame_rate || !frame_rate->den)
+sample_rate = 0;
+else
+sample_rate = ((int64_t)picture_size * frame_rate->num) / 
frame_rate->den;
+
+if (picture_size <= 0) {
+return 0;
+} else if (sample_rate <= 829440 && picture_size <= 36864) {
+return 0x10;
+} else if (sample_rate <= 2764800&& picture_size <= 73728) {
+return 0x11;
+} else if (sample_rate <= 4608000&& picture_size <= 122880) {
+return 0x20;
+} else if (sample_rate <= 9216000&& picture_size <= 245760) {
+return 0x21;
+} else if (sample_rate <= 20736000   && picture_size <= 552960) {
+return 0x30;
+} else if (sample_rate <= 36864000   && picture_size <= 983040) {
+return 0x31;
+} else if (sample_rate <= 83558400   && picture_size <= 2228224) {
+return 0x40;
+} else if (sample_rate <= 160432128  && picture_size <= 2228224) {
+return 0x41;
+} else if (sample_rate <= 311951360  && picture_size <= 8912896) {
+return 0x50;
+} else if (sample_rate <= 588251136  && picture_size <= 8912896) {
+return 0x51;
+} else if (sample_rate <= 1176502272 && picture_size <= 8912896) {
+return 0x52;
+} else if (sample_rate <= 1176502272 && picture_size <= 35651584) {
+return 0x60;
+} else if (sample_rate <= 2353004544 && picture_size <= 35651584) {
+return 0x61;
+} else if (sample_rate <= 4706009088 && picture_size <= 35651584) {
+return 0x62;
+} else {
+return 0;
+}
+}
+
 int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par,
-  VPCC *vpcc)
+  AVRational *frame_rate, VPCC *vpcc)
 {
 int profile = par->profile;
-int level = par->level == FF_LEVEL_UNKNOWN ? 0 : par->level;
+int level = par->level == FF_LEVEL_UNKNOWN ?
+get_vp9_level(par, frame_rate) : par->level;
 int bit_depth = get_bit_depth(s, par->format);
 int vpx_chroma_subsampling =
 get_vpx_chroma_subsampling(s, par->format, par->chroma_location);
@@ -105,7 +152,7 @@ int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb,
 VPCC vpcc;
 int ret;
 
-ret = ff_isom_get_vpcc_features(s, par, );
+ret = ff_isom_get_vpcc_features(s, par, NULL, );
 if (ret < 0)
 return ret;
 
diff --git a/libavformat/vpcc.h b/libavformat/vpcc.h
index d71ba05..e87bec5 100644
--- a/libavformat/vpcc.h
+++ b/libavformat/vpcc.h
@@ -53,6 +53,6 @@ int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb,
AVCodecParameters *par);
 
 int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par,
-  VPCC *vpcc);
+  AVRational *frame_rate, VPCC *vpcc);
 
 #endif /* AVFORMAT_VPCC_H */
-- 
2.7.4

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


[FFmpeg-devel] [PATCH v2 2/3] avformat/dashenc: Set VP9 codec string with profile, level and bitdepth

2018-04-23 Thread Karthick J
From: Karthick Jeyapal 

Otherwise some versions of chrome browser returns "codec not supported" error
---
 libavformat/dashenc.c | 34 --
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index fefe3ce..a5f58d4 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -45,6 +45,7 @@
 #include "isom.h"
 #include "os_support.h"
 #include "url.h"
+#include "vpcc.h"
 #include "dash.h"
 
 typedef struct Segment {
@@ -170,8 +171,23 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 }
 }
 
+static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par,
+  AVRational *frame_rate, char *str, int size) {
+VPCC vpcc;
+int ret = ff_isom_get_vpcc_features(s, par, frame_rate, );
+if (ret == 0) {
+av_strlcatf(str, size, "vp09.%02x.%02x.%02x",
+vpcc.profile, vpcc.level, vpcc.bitdepth);
+} else {
+// Default to just vp9 in case of error while finding out profile or 
level
+av_log(s, AV_LOG_WARNING, "Could not find VP9 profile and/or level\n");
+av_strlcpy(str, "vp9", size);
+}
+return;
+}
+
 static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
-  char *str, int size)
+  AVRational *frame_rate, char *str, int size)
 {
 const AVCodecTag *tags[2] = { NULL, NULL };
 uint32_t tag;
@@ -180,7 +196,11 @@ static void set_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
 // common Webm codecs are not part of RFC 6381
 for (i = 0; codecs[i].id; i++)
 if (codecs[i].id == par->codec_id) {
-av_strlcpy(str, codecs[i].str, size);
+if (codecs[i].id == AV_CODEC_ID_VP9) {
+set_vp9_codec_str(s, par, frame_rate, str, size);
+} else {
+av_strlcpy(str, codecs[i].str, size);
+}
 return;
 }
 
@@ -1032,7 +1052,8 @@ static int dash_init(AVFormatContext *s)
 c->has_video = 1;
 }
 
-set_codec_str(s, st->codecpar, os->codec_str, sizeof(os->codec_str));
+set_codec_str(s, st->codecpar, >avg_frame_rate, os->codec_str,
+  sizeof(os->codec_str));
 os->first_pts = AV_NOPTS_VALUE;
 os->max_pts = AV_NOPTS_VALUE;
 os->last_dts = AV_NOPTS_VALUE;
@@ -1132,7 +1153,8 @@ static void find_index_range(AVFormatContext *s, const 
char *full_path,
 }
 
 static int update_stream_extradata(AVFormatContext *s, OutputStream *os,
-   AVCodecParameters *par)
+   AVCodecParameters *par,
+   AVRational *frame_rate)
 {
 uint8_t *extradata;
 
@@ -1149,7 +1171,7 @@ static int update_stream_extradata(AVFormatContext *s, 
OutputStream *os,
 os->ctx->streams[0]->codecpar->extradata = extradata;
 os->ctx->streams[0]->codecpar->extradata_size = par->extradata_size;
 
-set_codec_str(s, par, os->codec_str, sizeof(os->codec_str));
+set_codec_str(s, par, frame_rate, os->codec_str, sizeof(os->codec_str));
 
 return 0;
 }
@@ -1298,7 +1320,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 int64_t seg_end_duration, elapsed_duration;
 int ret;
 
-ret = update_stream_extradata(s, os, st->codecpar);
+ret = update_stream_extradata(s, os, st->codecpar, >avg_frame_rate);
 if (ret < 0)
 return ret;
 
-- 
2.7.4

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Set mp4 as the default format for VP9

2018-04-18 Thread Karthick J
From: Karthick Jeyapal 

There is a separate muxer(webmdashenc.c) for supporting VP9+webm output in DASH.
Hence in this muxer we will focus on supporting VP9 in MP4
Have verified playout support of VP9+MP4 in Chrome and Firefox.
---
 libavformat/dashenc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5443e31..301ea1a 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1016,11 +1016,10 @@ static int dash_init(AVFormatContext *s)
 if (!ctx)
 return AVERROR(ENOMEM);
 
-// choose muxer based on codec: webm for VP8/9 and opus, mp4 otherwise
+// choose muxer based on codec: webm for VP8 and opus, mp4 otherwise
 // note: os->format_name is also used as part of the mimetype of the
 //   representation, e.g. video/
 if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
-s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP9 ||
 s->streams[i]->codecpar->codec_id == AV_CODEC_ID_OPUS ||
 s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VORBIS) {
 snprintf(os->format_name, sizeof(os->format_name), "webm");
-- 
2.7.4

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Set VP9 codec string with profile, level and bitdepth

2018-04-18 Thread Karthick J
From: Karthick Jeyapal 

Otherwise some versions of chrome browser returns "codec not supported" error
---
 libavformat/dashenc.c | 79 ++-
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 9e72636..5443e31 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -170,6 +170,79 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 }
 }
 
+static void set_vp9_codec_str(AVCodecParameters *par, char *str, int size) {
+int profile, level, bitdepth;
+int picture_size = par->width * par->height;
+switch (par->format) {
+case AV_PIX_FMT_YUV420P:
+case AV_PIX_FMT_YUVA420P:
+bitdepth = 8;
+profile = 0;
+break;
+case AV_PIX_FMT_YUV422P:
+case AV_PIX_FMT_YUV440P:
+case AV_PIX_FMT_GBRP:
+case AV_PIX_FMT_YUV444P:
+bitdepth = 8;
+profile = 1;
+break;
+case AV_PIX_FMT_YUV420P10:
+bitdepth = 10;
+profile = 2;
+break;
+case AV_PIX_FMT_YUV420P12:
+bitdepth = 12;
+profile = 2;
+break;
+case AV_PIX_FMT_YUV422P10:
+case AV_PIX_FMT_YUV440P10:
+case AV_PIX_FMT_GBRP10:
+case AV_PIX_FMT_YUV444P10:
+bitdepth = 10;
+profile = 3;
+break;
+case AV_PIX_FMT_YUV422P12:
+case AV_PIX_FMT_YUV440P12:
+case AV_PIX_FMT_GBRP12:
+case AV_PIX_FMT_YUV444P12:
+bitdepth = 12;
+profile = 3;
+break;
+default:
+goto error;
+}
+// Finding VP9 level accurately in a ffmpeg muxer is almost impossible.
+// Hence we will set approximate levels based on the width and height.
+if (picture_size <= 0) {
+goto error;
+} else if (picture_size <= 36864) {
+level = 0x10;
+} else if (picture_size <= 73728) {
+level = 0x11;
+} else if (picture_size <= 122880) {
+level = 0x20;
+} else if (picture_size <= 245760) {
+level = 0x21;
+} else if (picture_size <= 552960) {
+level = 0x30;
+} else if (picture_size <= 983040) {
+level = 0x31;
+} else if (picture_size <= 2228224) {
+level = 0x40;
+} else if (picture_size <= 8912896) {
+level = 0x50;
+} else if (picture_size <= 35651584) {
+level = 0x60;
+} else {
+goto error;
+}
+av_strlcatf(str, size, "vp09.%02x.%02x.%02x", profile, level, bitdepth);
+return;
+error:
+// Default to just vp9 in case of error while finding out profile or level
+av_strlcpy(str, "vp9", size);
+return;
+}
 static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
   char *str, int size)
 {
@@ -180,7 +253,11 @@ static void set_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
 // common Webm codecs are not part of RFC 6381
 for (i = 0; codecs[i].id; i++)
 if (codecs[i].id == par->codec_id) {
-av_strlcpy(str, codecs[i].str, size);
+if (codecs[i].id == AV_CODEC_ID_VP9) {
+set_vp9_codec_str(par, str, size);
+} else {
+av_strlcpy(str, codecs[i].str, size);
+}
 return;
 }
 
-- 
2.7.4

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Removed usage of deprecated 'filename' variable

2018-02-23 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index d6474f3..ebff3c5 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1307,7 +1307,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 //open the output context when the first frame of a segment is ready
 if (!c->single_file && !os->out) {
 AVDictionary *opts = NULL;
-const char *proto = avio_find_protocol_name(s->filename);
+const char *proto = avio_find_protocol_name(s->url);
 int use_rename = proto && !strcmp(proto, "file");
 os->filename[0] = os->full_path[0] = os->temp_path[0] = '\0';
 ff_dash_fill_tmpl_params(os->filename, sizeof(os->filename),
-- 
1.9.1

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


[FFmpeg-devel] [PATCH] MAINTAINERS: Adding myself as dashenc maintainer

2018-01-20 Thread Karthick J
From: Karthick Jeyapal 

If somebody else wants to maintain dashenc either now or in future,
I am absolutely fine with giving up this responsibility anytime.
But till then we need a maintainer for dashenc, and I am volunteering for that 
task.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e583926..1785851 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -394,6 +394,7 @@ Muxers/Demuxers:
   cdxl.cPaul B Mahol
   crc.c Michael Niedermayer
   dashdec.c Steven Liu
+  dashenc.c Karthick Jeyapal
   daud.cReimar Doeffinger
   dss.c Oleksij Rempel
   dtsdec.c  foo86
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/dashenc: Fix a resource leak when http persistent in enabled

2018-01-02 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 3345b89..2e4ff67 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1,6 +1,7 @@
 /*
  * MPEG-DASH ISO BMFF segmenter
  * Copyright (c) 2014 Martin Storsjo
+ * Copyright (c) 2018 Akamai Technologies, Inc.
  *
  * This file is part of FFmpeg.
  *
@@ -309,6 +310,9 @@ static void dash_free(AVFormatContext *s)
 av_free(os->segments);
 }
 av_freep(>streams);
+
+ff_format_io_close(s, >mpd_out);
+ff_format_io_close(s, >m3u8_out);
 }
 
 static void output_segment_list(OutputStream *os, AVIOContext *out, 
AVFormatContext *s,
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Signal http end of chunk(http_shutdown) explicitly

2018-01-02 Thread Karthick J
From: Karthick Jeyapal 

Currently http end of chunk is signalled implicitly in dashenc_io_open().
This mean playlists http writes would have to wait upto a segment duration to 
signal end of chunk causing delays.
This patch will fix that problem and improve performance.
---
 libavformat/dashenc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 2e4ff67..c9cc389 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -149,7 +149,10 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 ff_format_io_close(s, pb);
 #if CONFIG_HTTP_PROTOCOL
 } else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
 avio_flush(*pb);
+ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
 #endif
 }
 }
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Signal http end of chunk(http_shutdown) explicitly

2018-01-01 Thread Karthick J
From: Karthick Jeyapal 

Currently http end of chunk is signalled implicitly in dashenc_io_open().
This mean playlists http writes would have to wait upto a segment duration to 
signal end of chunk causing delays.
This patch will fix that problem and improve performance.
---
 libavformat/dashenc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index c4c112b..c328db2 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -149,7 +149,10 @@ static void dashenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filenam
 ff_format_io_close(s, pb);
 #if CONFIG_HTTP_PROTOCOL
 } else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
 avio_flush(*pb);
+ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
 #endif
 }
 }
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Fix a resource leak when http persistent in enabled

2018-01-01 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 3345b89..c4c112b 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1,6 +1,7 @@
 /*
  * MPEG-DASH ISO BMFF segmenter
  * Copyright (c) 2014 Martin Storsjo
+ * Copyright (c) 2018 Akamai Technologies, Inc.
  *
  * This file is part of FFmpeg.
  *
@@ -1317,6 +1318,16 @@ static int dash_write_trailer(AVFormatContext *s)
 }
 dash_flush(s, 1, -1);
 
+if (c->http_persistent) {
+int i;
+for (i = 0; i < s->nb_streams; i++) {
+OutputStream *os = >streams[i];
+ff_format_io_close(s, >out);
+}
+ff_format_io_close(s, >mpd_out);
+ff_format_io_close(s, >m3u8_out);
+}
+
 if (c->remove_at_exit) {
 char filename[1024];
 int i;
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v3] avformat/hlsenc: Add CODECS attribute to master playlist

2017-12-28 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c |  2 +-
 libavformat/hlsenc.c  | 67 ++-
 libavformat/hlsplaylist.c |  5 +++-
 libavformat/hlsplaylist.h |  3 ++-
 4 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index a3eb522..400d767 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -780,7 +780,7 @@ static int write_manifest(AVFormatContext *s, int final)
 stream_bitrate += max_audio_bitrate;
 }
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup);
+ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup, NULL);
 }
 avio_close(out);
 if (use_rename)
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 5cff3b4..5fc907c 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -58,6 +58,11 @@ typedef enum {
   HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2,  // MMDDhhmmss
 } StartSequenceSourceType;
 
+typedef enum {
+CODEC_ATTRIBUTE_WRITTEN = 0,
+CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN,
+} CodecAttributeStatus;
+
 #define KEYSIZE 16
 #define LINE_BUFFER_SIZE 1024
 #define HLS_MICROSECOND_UNIT   100
@@ -142,6 +147,8 @@ typedef struct VariantStream {
 int fmp4_init_mode;
 
 AVStream **streams;
+char codec_attr[128];
+CodecAttributeStatus attr_status;
 unsigned int nb_streams;
 int m3u8_created; /* status of media play-list creation */
 char *agroup; /* audio group name */
@@ -296,6 +303,51 @@ static void set_http_options(AVFormatContext *s, 
AVDictionary **options, HLSCont
 
 }
 
+static void write_codec_attr(AVStream *st, VariantStream *vs) {
+int codec_strlen = strlen(vs->codec_attr);
+char attr[32];
+
+if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
+return;
+if (vs->attr_status == CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN)
+return;
+
+if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
+uint8_t *data = st->codecpar->extradata;
+if ((data[0] | data[1] | data[2]) == 0 && data[3] == 1 && (data[4] & 
0x1F) == 7) {
+snprintf(attr, sizeof(attr),
+ "avc1.%02x%02x%02x", data[5], data[6], data[7]);
+} else {
+goto fail;
+}
+} else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
+snprintf(attr, sizeof(attr), "mp4a.40.33");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
+snprintf(attr, sizeof(attr), "mp4a.40.34");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
+/* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 
and 29 respectively */
+snprintf(attr, sizeof(attr), "mp4a.40.2");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
+snprintf(attr, sizeof(attr), "ac-3");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
+snprintf(attr, sizeof(attr), "ec-3");
+} else {
+goto fail;
+}
+// Don't write the same attribute multiple times
+if (!av_stristr(vs->codec_attr, attr)) {
+snprintf(vs->codec_attr + codec_strlen,
+ sizeof(vs->codec_attr) - codec_strlen,
+ "%s%s", codec_strlen ? "," : "", attr);
+}
+return;
+
+fail:
+vs->codec_attr[0] = '\0';
+vs->attr_status = CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN;
+return;
+}
+
 static int replace_int_data_in_filename(char *buf, int buf_size, const char 
*filename, char placeholder, int64_t number)
 {
 const char *p;
@@ -1233,7 +1285,7 @@ static int create_master_playlist(AVFormatContext *s,
 bandwidth += bandwidth / 10;
 
 ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, 
m3u8_rel_name,
-aud_st ? vs->agroup : NULL);
+aud_st ? vs->agroup : NULL, vs->codec_attr);
 
 av_freep(_rel_name);
 }
@@ -1762,6 +1814,19 @@ static int hls_write_header(AVFormatContext *s)
 continue;
 }
 avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, 
inner_st->time_base.num, inner_st->time_base.den);
+write_codec_attr(outer_st, vs);
+
+}
+/* Update the Codec Attr string for the mapped audio groups */
+if (vs->has_video && vs->agroup) {
+for (j = 0; j < hls->nb_varstreams; j++) {
+VariantStream *vs_agroup = &(hls->var_streams[j]);
+if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
+vs_agroup->agroup &&
+!av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
+write_codec_attr(vs_agroup->streams[0], vs);
+}
+}
 }
 }
 fail:
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index 098dc89..b8a3a14 

[FFmpeg-devel] [PATCH v2] avformat/hlsenc: Add CODECS attribute to master playlist

2017-12-28 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c |  2 +-
 libavformat/hlsenc.c  | 67 ++-
 libavformat/hlsplaylist.c |  5 +++-
 libavformat/hlsplaylist.h |  3 ++-
 4 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 478a384..8797959 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -760,7 +760,7 @@ static int write_manifest(AVFormatContext *s, int final)
 AVStream *st = s->streams[i];
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
 ff_hls_write_stream_info(st, out, st->codecpar->bit_rate,
-playlist_file, NULL);
+playlist_file, NULL, NULL);
 }
 avio_close(out);
 if (use_rename)
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 74f66ce..bb442f5 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -58,6 +58,11 @@ typedef enum {
   HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2,  // MMDDhhmmss
 } StartSequenceSourceType;
 
+typedef enum {
+CODEC_ATTRIBUTE_WRITTEN = 0,
+CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN,
+} CodecAttributeStatus;
+
 #define KEYSIZE 16
 #define LINE_BUFFER_SIZE 1024
 #define HLS_MICROSECOND_UNIT   100
@@ -142,6 +147,8 @@ typedef struct VariantStream {
 int fmp4_init_mode;
 
 AVStream **streams;
+char codec_attr[128];
+CodecAttributeStatus attr_status;
 unsigned int nb_streams;
 int m3u8_created; /* status of media play-list creation */
 char *agroup; /* audio group name */
@@ -296,6 +303,51 @@ static void set_http_options(AVFormatContext *s, 
AVDictionary **options, HLSCont
 
 }
 
+static void write_codec_attr(AVStream *st, VariantStream *vs) {
+int codec_strlen = strlen(vs->codec_attr);
+char attr[32];
+
+if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
+return;
+if (vs->attr_status == CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN)
+return;
+
+if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
+uint8_t *data = st->codecpar->extradata;
+if ((data[0] | data[1] | data[2]) == 0 && data[3] == 1 && (data[4] & 
0x1F) == 7) {
+snprintf(attr, sizeof(attr),
+ "avc1.%02x%02x%02x", data[5], data[6], data[7]);
+} else {
+goto fail;
+}
+} else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
+snprintf(attr, sizeof(attr), "mp4a.40.33");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
+snprintf(attr, sizeof(attr), "mp4a.40.34");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
+/* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 
and 29 respectively */
+snprintf(attr, sizeof(attr), "mp4a.40.2");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
+snprintf(attr, sizeof(attr), "ac-3");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
+snprintf(attr, sizeof(attr), "ec-3");
+} else {
+goto fail;
+}
+// Don't write the same attribute multiple times
+if (!av_stristr(vs->codec_attr, attr)) {
+snprintf(vs->codec_attr + codec_strlen,
+ sizeof(vs->codec_attr) - codec_strlen,
+ "%s%s", codec_strlen ? "," : "", attr);
+}
+return;
+
+fail:
+vs->codec_attr[0] = '\0';
+vs->attr_status = CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN;
+return;
+}
+
 static int replace_int_data_in_filename(char *buf, int buf_size, const char 
*filename, char placeholder, int64_t number)
 {
 const char *p;
@@ -1235,7 +1287,7 @@ static int create_master_playlist(AVFormatContext *s,
 bandwidth += bandwidth / 10;
 
 ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, 
m3u8_rel_name,
-aud_st ? vs->agroup : NULL);
+aud_st ? vs->agroup : NULL, vs->codec_attr);
 
 av_freep(_rel_name);
 }
@@ -1764,6 +1816,19 @@ static int hls_write_header(AVFormatContext *s)
 continue;
 }
 avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, 
inner_st->time_base.num, inner_st->time_base.den);
+write_codec_attr(outer_st, vs);
+
+}
+/* Update the Codec Attr string for the mapped audio groups */
+if (vs->has_video && vs->agroup) {
+for (j = 0; j < hls->nb_varstreams; j++) {
+VariantStream *vs_agroup = &(hls->var_streams[j]);
+if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
+vs_agroup->agroup &&
+!av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
+write_codec_attr(vs_agroup->streams[0], vs);
+}
+}
 }
 }
 fail:
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index 42f059a..99231c9 100644
--- a/libavformat/hlsplaylist.c
+++ 

[FFmpeg-devel] [PATCH] avformat/hlsenc: Add CODECS attribute to master playlist

2017-12-28 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c |  2 +-
 libavformat/hlsenc.c  | 67 ++-
 libavformat/hlsplaylist.c |  5 +++-
 libavformat/hlsplaylist.h |  3 ++-
 4 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 478a384..8797959 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -760,7 +760,7 @@ static int write_manifest(AVFormatContext *s, int final)
 AVStream *st = s->streams[i];
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
 ff_hls_write_stream_info(st, out, st->codecpar->bit_rate,
-playlist_file, NULL);
+playlist_file, NULL, NULL);
 }
 avio_close(out);
 if (use_rename)
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 74f66ce..1a84799 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -58,6 +58,11 @@ typedef enum {
   HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2,  // MMDDhhmmss
 } StartSequenceSourceType;
 
+typedef enum {
+CODEC_ATTRIBUTE_WRITTEN = 0,
+CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN,
+} CodecAttributeStatus;
+
 #define KEYSIZE 16
 #define LINE_BUFFER_SIZE 1024
 #define HLS_MICROSECOND_UNIT   100
@@ -142,6 +147,8 @@ typedef struct VariantStream {
 int fmp4_init_mode;
 
 AVStream **streams;
+char codec_attr[128];
+CodecAttributeStatus attr_status;
 unsigned int nb_streams;
 int m3u8_created; /* status of media play-list creation */
 char *agroup; /* audio group name */
@@ -296,6 +303,51 @@ static void set_http_options(AVFormatContext *s, 
AVDictionary **options, HLSCont
 
 }
 
+static void write_codec_attr(AVStream *st, VariantStream *vs) {
+int codec_strlen = strlen(vs->codec_attr);
+char attr[32];
+
+if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
+return;
+if (vs->attr_status == CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN)
+return;
+
+if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
+uint8_t *data = st->codecpar->extradata;
+if ((data[0] | data[1] | data[2]) == 0 && data[3] == 1 && (data[4] & 
0x1F) == 7) {
+snprintf(attr, sizeof(attr),
+ "avc1.%02x%02x%02x", data[5], data[6], data[7]);
+} else {
+goto fail;
+}
+} else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
+snprintf(attr, sizeof(attr), "mp4a.40.33");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
+snprintf(attr, sizeof(attr), "mp4a.40.34");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
+/* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 
and 29 respectively */
+snprintf(attr, sizeof(attr), "mp4a.40.2");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
+snprintf(attr, sizeof(attr), "ac-3");
+} else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
+snprintf(attr, sizeof(attr), "ec-3");
+} else {
+goto fail;
+}
+// Don't write the same attribute multiple times
+if (!strstr(vs->codec_attr, attr)) {
+snprintf(vs->codec_attr + codec_strlen,
+ sizeof(vs->codec_attr) - codec_strlen,
+ "%s%s", codec_strlen ? "," : "", attr);
+}
+return;
+
+fail:
+vs->codec_attr[0] = '\0';
+vs->attr_status = CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN;
+return;
+}
+
 static int replace_int_data_in_filename(char *buf, int buf_size, const char 
*filename, char placeholder, int64_t number)
 {
 const char *p;
@@ -1235,7 +1287,7 @@ static int create_master_playlist(AVFormatContext *s,
 bandwidth += bandwidth / 10;
 
 ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, 
m3u8_rel_name,
-aud_st ? vs->agroup : NULL);
+aud_st ? vs->agroup : NULL, vs->codec_attr);
 
 av_freep(_rel_name);
 }
@@ -1764,6 +1816,19 @@ static int hls_write_header(AVFormatContext *s)
 continue;
 }
 avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, 
inner_st->time_base.num, inner_st->time_base.den);
+write_codec_attr(outer_st, vs);
+
+}
+/* Update the Codec Attr string for the mapped audio groups */
+if (vs->has_video && vs->agroup) {
+for (j = 0; j < hls->nb_varstreams; j++) {
+VariantStream *vs_agroup = &(hls->var_streams[j]);
+if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
+vs_agroup->agroup &&
+!av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
+write_codec_attr(vs_agroup->streams[0], vs);
+}
+}
 }
 }
 fail:
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index 42f059a..99231c9 100644
--- a/libavformat/hlsplaylist.c
+++ 

[FFmpeg-devel] [PATCH 3/3] avformat/dashenc: Addition of #EXT-X-MEDIA tag and AUDIO attribute

2017-12-26 Thread Karthick J
From: Karthick Jeyapal 

This is required for AV playout from master.m3u8.
Otherwise master.m3u8 lists only video-only and/or audio-only streams.
---
 libavformat/dashenc.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 478a384..a3eb522 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -737,6 +737,9 @@ static int write_manifest(AVFormatContext *s, int final)
 
 if (c->hls_playlist && !c->master_playlist_created) {
 char filename_hls[1024];
+const char *audio_group = "A1";
+int is_default = 1;
+int max_audio_bitrate = 0;
 
 if (*c->dirname)
 snprintf(filename_hls, sizeof(filename_hls), "%s/master.m3u8", 
c->dirname);
@@ -758,9 +761,26 @@ static int write_manifest(AVFormatContext *s, int final)
 for (i = 0; i < s->nb_streams; i++) {
 char playlist_file[64];
 AVStream *st = s->streams[i];
+if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
+continue;
+get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
+ff_hls_write_audio_rendition(out, (char *)audio_group,
+ playlist_file, i, is_default);
+max_audio_bitrate = FFMAX(st->codecpar->bit_rate, 
max_audio_bitrate);
+is_default = 0;
+}
+
+for (i = 0; i < s->nb_streams; i++) {
+char playlist_file[64];
+AVStream *st = s->streams[i];
+char *agroup = NULL;
+int stream_bitrate = st->codecpar->bit_rate;
+if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && 
max_audio_bitrate) {
+agroup = (char *)audio_group;
+stream_bitrate += max_audio_bitrate;
+}
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, 
i);
-ff_hls_write_stream_info(st, out, st->codecpar->bit_rate,
-playlist_file, NULL);
+ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, 
agroup);
 }
 avio_close(out);
 if (use_rename)
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 1/3] avformat/hlsenc: Modularized audio rendition playlist write to allow reuse

2017-12-26 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c  | 6 ++
 libavformat/hlsplaylist.c | 9 +
 libavformat/hlsplaylist.h | 1 +
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 74f66ce..fe531fb 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1169,10 +1169,8 @@ static int create_master_playlist(AVFormatContext *s,
 goto fail;
 }
 
-avio_printf(hls->m3u8_out, 
"#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"group_%s\"",
-vs->agroup);
-avio_printf(hls->m3u8_out, 
",NAME=\"audio_0\",DEFAULT=YES,URI=\"%s\"\n",
-m3u8_rel_name);
+ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name);
+
 av_freep(_rel_name);
 }
 
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index 42f059a..a065eda 100644
--- a/libavformat/hlsplaylist.c
+++ b/libavformat/hlsplaylist.c
@@ -35,6 +35,15 @@ void ff_hls_write_playlist_version(AVIOContext *out, int 
version) {
 avio_printf(out, "#EXT-X-VERSION:%d\n", version);
 }
 
+void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
+  char *filename) {
+if (!out || !agroup || !filename)
+return;
+
+avio_printf(out, "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"group_%s\"", agroup);
+avio_printf(out, ",NAME=\"audio_0\",DEFAULT=YES,URI=\"%s\"\n", filename);
+}
+
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
   int bandwidth, char *filename, char *agroup) {
 if (!out || !filename)
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index ac03550..518cfc2 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -37,6 +37,7 @@ typedef enum {
 } PlaylistType;
 
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
+void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup, char 
*filename);
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
   int bandwidth, char *filename, char *agroup);
 void ff_hls_write_playlist_header(AVIOContext *out, int version, int 
allowcache,
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/3] avformat/hlsplaylist: Audio rendition's name and defaultness made configurable

2017-12-26 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c  | 2 +-
 libavformat/hlsplaylist.c | 5 +++--
 libavformat/hlsplaylist.h | 3 ++-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index fe531fb..5cff3b4 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1169,7 +1169,7 @@ static int create_master_playlist(AVFormatContext *s,
 goto fail;
 }
 
-ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name);
+ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, 
0, 1);
 
 av_freep(_rel_name);
 }
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index a065eda..098dc89 100644
--- a/libavformat/hlsplaylist.c
+++ b/libavformat/hlsplaylist.c
@@ -36,12 +36,13 @@ void ff_hls_write_playlist_version(AVIOContext *out, int 
version) {
 }
 
 void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
-  char *filename) {
+  char *filename, int name_id, int is_default) 
{
 if (!out || !agroup || !filename)
 return;
 
 avio_printf(out, "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"group_%s\"", agroup);
-avio_printf(out, ",NAME=\"audio_0\",DEFAULT=YES,URI=\"%s\"\n", filename);
+avio_printf(out, ",NAME=\"audio_%d\",DEFAULT=%s,URI=\"%s\"\n", name_id,
+ is_default ? "YES" : "NO", filename);
 }
 
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index 518cfc2..9969315 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -37,7 +37,8 @@ typedef enum {
 } PlaylistType;
 
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
-void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup, char 
*filename);
+void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
+  char *filename, int name_id, int is_default);
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
   int bandwidth, char *filename, char *agroup);
 void ff_hls_write_playlist_header(AVIOContext *out, int version, int 
allowcache,
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/hlsenc: Signal http end of chunk(http_shutdown) during hlsenc_io_close()

2017-12-22 Thread Karthick J
From: Karthick Jeyapal 

Currently http end of chunk is signalled implicitly in hlsenc_io_open().
This mean playlists http writes would have to wait upto a segment duration to 
signal end of chunk causing delays.
This patch will fix that problem and improve performance.
---
 libavformat/hlsenc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 0095ca4..7b9bbc0 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -268,8 +268,13 @@ static void hlsenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filename
 
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
+#if CONFIG_HTTP_PROTOCOL
 } else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
 avio_flush(*pb);
+ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
+#endif
 }
 }
 
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 1/2] avformat/http: Avoid calling http_shutdown() if end of chunk is signalled already

2017-12-22 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/http.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index cf86adc..4635a9a 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -307,9 +307,11 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
 AVDictionary *options = NULL;
 int ret;
 
-ret = http_shutdown(h, h->flags);
-if (ret < 0)
-return ret;
+if (!s->end_chunked_post) {
+ret = http_shutdown(h, h->flags);
+if (ret < 0)
+return ret;
+}
 
 s->end_chunked_post = 0;
 s->chunkend  = 0;
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 1/2] avformat/http: Added a library-internal API for signalling end of chunk

2017-12-21 Thread Karthick J
From: Karthick Jeyapal 

Right now there is no explicit way to signal end of chunk, when http_multiple 
is set.
ff_http_do_new_request() function implicitly signals end of chunk. But that 
could be too late for certain applications.
Hence added a new function ff_http_signal_end_of_chunk() which could be used 
internally within libavformat.
---
 libavformat/http.c | 17 ++---
 libavformat/http.h |  9 +
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index cf86adc..d8224de 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -307,9 +307,11 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
 AVDictionary *options = NULL;
 int ret;
 
-ret = http_shutdown(h, h->flags);
-if (ret < 0)
-return ret;
+if (!s->end_chunked_post) {
+ret = http_shutdown(h, h->flags);
+if (ret < 0)
+return ret;
+}
 
 s->end_chunked_post = 0;
 s->chunkend  = 0;
@@ -325,6 +327,15 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
 return ret;
 }
 
+int ff_http_signal_end_of_chunk(URLContext *h) {
+HTTPContext *s = h->priv_data;
+int ret = 0;
+if (!s->end_chunked_post) {
+ret = http_shutdown(h, h->flags);
+}
+return ret;
+}
+
 int ff_http_averror(int status_code, int default_averror)
 {
 switch (status_code) {
diff --git a/libavformat/http.h b/libavformat/http.h
index 7d02713..0eaeb48 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -47,6 +47,15 @@ void ff_http_init_auth_state(URLContext *dest, const 
URLContext *src);
  */
 int ff_http_do_new_request(URLContext *h, const char *uri);
 
+/**
+ * Send a end of chunk signal(sends a string "0\r\n\r\n"), if applicable.
+ *
+ * @param h pointer to the resource
+ * @return a negative value if an error condition occurred, 0
+ * otherwise
+ */
+int ff_http_signal_end_of_chunk(URLContext *h);
+
 int ff_http_averror(int status_code, int default_averror);
 
 #endif /* AVFORMAT_HTTP_H */
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/2] avformat/hlsenc: Signal http end of chunk explicitly during hlsenc_io_close()

2017-12-21 Thread Karthick J
From: Karthick Jeyapal 

Currently http end of chunk is called implicitly in hlsenc_io_open().
This mean playlists http writes would have to wait upto a segment duration to 
signal end of chunk causing delays.
This patch will fix that problem and improve performance.
---
 libavformat/hlsenc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 0095ca4..65182c5 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -268,8 +268,13 @@ static void hlsenc_io_close(AVFormatContext *s, 
AVIOContext **pb, char *filename
 
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
+#if CONFIG_HTTP_PROTOCOL
 } else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
 avio_flush(*pb);
+ff_http_signal_end_of_chunk(http_url_context);
+#endif
 }
 }
 
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Fix the EXT-X-TARGETDURATION as per the hls specification

2017-12-21 Thread Karthick J
From: Karthick Jeyapal 

The HLS specification states the following about EXT-X-TARGETDURATION

4.3.3.1.  EXT-X-TARGETDURATION

   The EXT-X-TARGETDURATION tag specifies the maximum Media Segment
   duration.  The EXTINF duration of each Media Segment in the Playlist
   file, when rounded to the nearest integer, MUST be less than or equal
   to the target duration; longer segments can trigger playback stalls
   or other errors.  It applies to the entire Playlist file.  Its format
   is:

   #EXT-X-TARGETDURATION:

   where s is a decimal-integer indicating the target duration in
   seconds.  The EXT-X-TARGETDURATION tag is REQUIRED.

Currently the dashenc rounds the duration to the next integer,
rather than rounding the duration to the nearest integer.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5687530..5368a23 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -358,7 +358,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 Segment *seg = os->segments[i];
 double duration = (double) seg->duration / timescale;
 if (target_duration <= duration)
-target_duration = hls_get_int_from_double(duration);
+target_duration = lrint(duration);
 }
 
 ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/2] avformat/hlsenc: Moved hls_get_int_from_double() function locally to hlsenc.c

2017-12-21 Thread Karthick J
From: Karthick Jeyapal 

dashenc no longer needs this function.
---
 libavformat/hlsenc.c  | 5 +
 libavformat/hlsplaylist.h | 5 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 29fc1d4..14a9a12 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -240,6 +240,11 @@ static int mkdir_p(const char *path) {
 return ret;
 }
 
+static int hls_get_int_from_double(double val)
+{
+return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
+}
+
 static int is_http_proto(char *filename) {
 const char *proto = avio_find_protocol_name(filename);
 return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, 
"https")) : 0;
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index 48d71b7..fe19f34 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -36,11 +36,6 @@ typedef enum {
 PLAYLIST_TYPE_NB,
 } PlaylistType;
 
-static inline int hls_get_int_from_double(double val)
-{
-return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
-}
-
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
   int bandwidth, char *filename);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH] avformat/dashenc: Fix the EXT-X-TARGETDURATION as per the hls specification

2017-12-21 Thread Karthick J
From: Karthick Jeyapal 

The HLS specification states the following about EXT-X-TARGETDURATION

4.3.3.1.  EXT-X-TARGETDURATION

   The EXT-X-TARGETDURATION tag specifies the maximum Media Segment
   duration.  The EXTINF duration of each Media Segment in the Playlist
   file, when rounded to the nearest integer, MUST be less than or equal
   to the target duration; longer segments can trigger playback stalls
   or other errors.  It applies to the entire Playlist file.  Its format
   is:

   #EXT-X-TARGETDURATION:

   where s is a decimal-integer indicating the target duration in
   seconds.  The EXT-X-TARGETDURATION tag is REQUIRED.

Currently the dashenc rounds the duration to the next integer,
rather than rounding the duration to the nearest integer.
---
 libavformat/dashenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5687530..5368a23 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -358,7 +358,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 Segment *seg = os->segments[i];
 double duration = (double) seg->duration / timescale;
 if (target_duration <= duration)
-target_duration = hls_get_int_from_double(duration);
+target_duration = lrint(duration);
 }
 
 ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
-- 
1.9.1

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


[FFmpeg-devel] [PATCH] avformat/hlsenc: Fix a memory leak when http_persistent is 1

2017-12-18 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index e3442c3..5ee28ea 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1918,6 +1918,8 @@ static int hls_write_trailer(struct AVFormatContext *s)
 av_freep(>baseurl);
 }
 
+ff_format_io_close(s, >m3u8_out);
+ff_format_io_close(s, >sub_m3u8_out);
 av_freep(>key_basename);
 av_freep(>var_streams);
 av_freep(>master_m3u8_url);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Persistent HTTP connections supported as an option

2017-12-16 Thread Karthick J
From: Karthick Jeyapal 

---
 doc/muxers.texi   |  2 ++
 libavformat/dashenc.c | 67 +--
 2 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 3d0c7bf..d6415db 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -249,6 +249,8 @@ DASH-templated name to used for the media segments. Default 
is "chunk-stream$Rep
 URL of the page that will return the UTC timestamp in ISO format. Example: 
"https://time.akamai.com/?iso;
 @item -http_user_agent @var{user_agent}
 Override User-Agent field in HTTP header. Applicable only for HTTP output.
+@item -http_persistent @var{http_persistent}
+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.
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5687530..e7d1a0d 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -37,6 +37,9 @@
 #include "avformat.h"
 #include "avio_internal.h"
 #include "hlsplaylist.h"
+#if CONFIG_HTTP_PROTOCOL
+#include "http.h"
+#endif
 #include "internal.h"
 #include "isom.h"
 #include "os_support.h"
@@ -103,7 +106,10 @@ typedef struct DASHContext {
 const char *utc_timing_url;
 const char *user_agent;
 int hls_playlist;
+int http_persistent;
 int master_playlist_created;
+AVIOContext *mpd_out;
+AVIOContext *m3u8_out;
 } DASHContext;
 
 static struct codec_string {
@@ -117,6 +123,36 @@ static struct codec_string {
 { 0, NULL }
 };
 
+static int dashenc_io_open(AVFormatContext *s, AVIOContext **pb, char 
*filename,
+   AVDictionary **options) {
+DASHContext *c = s->priv_data;
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
+int err = AVERROR_MUXER_NOT_FOUND;
+if (!*pb || !http_base_proto || !c->http_persistent) {
+err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
+#if CONFIG_HTTP_PROTOCOL
+} else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
+err = ff_http_do_new_request(http_url_context, filename);
+#endif
+}
+return err;
+}
+
+static void dashenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
+DASHContext *c = s->priv_data;
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
+
+if (!http_base_proto || !c->http_persistent) {
+ff_format_io_close(s, pb);
+#if CONFIG_HTTP_PROTOCOL
+} else {
+avio_flush(*pb);
+#endif
+}
+}
+
 static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
   char *str, int size)
 {
@@ -218,6 +254,8 @@ static void set_http_options(AVDictionary **options, 
DASHContext *c)
 {
 if (c->user_agent)
 av_dict_set(options, "user_agent", c->user_agent, 0);
+if (c->http_persistent)
+av_dict_set_int(options, "multiple_requests", 1, 0);
 }
 
 static void get_hls_playlist_name(char *playlist_name, int string_size,
@@ -273,9 +311,10 @@ static void dash_free(AVFormatContext *s)
 av_freep(>streams);
 }
 
-static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c,
+static void output_segment_list(OutputStream *os, AVIOContext *out, 
AVFormatContext *s,
 int representation_id, int final)
 {
+DASHContext *c = s->priv_data;
 int i, start_index = 0, start_number = 1;
 if (c->window_size) {
 start_index  = FFMAX(os->nb_segments   - c->window_size, 0);
@@ -339,7 +378,6 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 int timescale = os->ctx->streams[0]->time_base.den;
 char temp_filename_hls[1024];
 char filename_hls[1024];
-AVIOContext *out_hls = NULL;
 AVDictionary *http_opts = NULL;
 int target_duration = 0;
 int ret = 0;
@@ -352,7 +390,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
 
 set_http_options(_opts, c);
-avio_open2(_hls, temp_filename_hls, AVIO_FLAG_WRITE, NULL, 
_opts);
+dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
 av_dict_free(_opts);
 for (i = start_index; i < os->nb_segments; i++) {
 Segment *seg = os->segments[i];
@@ -361,15 +399,15 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 target_duration = hls_get_int_from_double(duration);
 }
 
-ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
+ff_hls_write_playlist_header(c->m3u8_out, 6, -1, 

[FFmpeg-devel] [PATCH v2 1/2] avformat/hlsenc, utils: Moved is_http_proto from hlsenc to utils for re-use

2017-12-16 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c   | 12 +++-
 libavformat/internal.h |  8 
 libavformat/utils.c|  5 +
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index e3442c3..03d54c7 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -240,15 +240,10 @@ static int mkdir_p(const char *path) {
 return ret;
 }
 
-static int is_http_proto(char *filename) {
-const char *proto = avio_find_protocol_name(filename);
-return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, 
"https")) : 0;
-}
-
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
   AVDictionary **options) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = filename ? is_http_proto(filename) : 0;
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
 int err = AVERROR_MUXER_NOT_FOUND;
 if (!*pb || !http_base_proto || !hls->http_persistent) {
 err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
@@ -264,8 +259,7 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 
 static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = filename ? is_http_proto(filename) : 0;
-
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
 } else {
@@ -275,7 +269,7 @@ static void hlsenc_io_close(AVFormatContext *s, AVIOContext 
**pb, char *filename
 
 static void set_http_options(AVFormatContext *s, AVDictionary **options, 
HLSContext *c)
 {
-int http_base_proto = is_http_proto(s->filename);
+int http_base_proto = ff_is_http_proto(s->filename);
 
 if (c->method) {
 av_dict_set(options, "method", c->method, 0);
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 36a5721..8f168c9 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -619,6 +619,14 @@ int ff_format_output_open(AVFormatContext *s, const char 
*url, AVDictionary **op
 void ff_format_io_close(AVFormatContext *s, AVIOContext **pb);
 
 /**
+ * Utility function to check if the file uses http or https protocol
+ *
+ * @param s AVFormatContext
+ * @param filename URL or file name to open for writing
+ */
+int ff_is_http_proto(char *filename);
+
+/**
  * Parse creation_time in AVFormatContext metadata if exists and warn if the
  * parsing fails.
  *
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 84e4920..f18a7c8 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -5459,6 +5459,11 @@ void ff_format_io_close(AVFormatContext *s, AVIOContext 
**pb)
 *pb = NULL;
 }
 
+int ff_is_http_proto(char *filename) {
+const char *proto = avio_find_protocol_name(filename);
+return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, 
"https")) : 0;
+}
+
 int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, 
int return_seconds)
 {
 AVDictionaryEntry *entry;
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Persistent HTTP connections supported as an option

2017-12-15 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/dashenc.c | 67 +--
 1 file changed, 54 insertions(+), 13 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5687530..e7d1a0d 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -37,6 +37,9 @@
 #include "avformat.h"
 #include "avio_internal.h"
 #include "hlsplaylist.h"
+#if CONFIG_HTTP_PROTOCOL
+#include "http.h"
+#endif
 #include "internal.h"
 #include "isom.h"
 #include "os_support.h"
@@ -103,7 +106,10 @@ typedef struct DASHContext {
 const char *utc_timing_url;
 const char *user_agent;
 int hls_playlist;
+int http_persistent;
 int master_playlist_created;
+AVIOContext *mpd_out;
+AVIOContext *m3u8_out;
 } DASHContext;
 
 static struct codec_string {
@@ -117,6 +123,36 @@ static struct codec_string {
 { 0, NULL }
 };
 
+static int dashenc_io_open(AVFormatContext *s, AVIOContext **pb, char 
*filename,
+   AVDictionary **options) {
+DASHContext *c = s->priv_data;
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
+int err = AVERROR_MUXER_NOT_FOUND;
+if (!*pb || !http_base_proto || !c->http_persistent) {
+err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
+#if CONFIG_HTTP_PROTOCOL
+} else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
+err = ff_http_do_new_request(http_url_context, filename);
+#endif
+}
+return err;
+}
+
+static void dashenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
+DASHContext *c = s->priv_data;
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
+
+if (!http_base_proto || !c->http_persistent) {
+ff_format_io_close(s, pb);
+#if CONFIG_HTTP_PROTOCOL
+} else {
+avio_flush(*pb);
+#endif
+}
+}
+
 static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
   char *str, int size)
 {
@@ -218,6 +254,8 @@ static void set_http_options(AVDictionary **options, 
DASHContext *c)
 {
 if (c->user_agent)
 av_dict_set(options, "user_agent", c->user_agent, 0);
+if (c->http_persistent)
+av_dict_set_int(options, "multiple_requests", 1, 0);
 }
 
 static void get_hls_playlist_name(char *playlist_name, int string_size,
@@ -273,9 +311,10 @@ static void dash_free(AVFormatContext *s)
 av_freep(>streams);
 }
 
-static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c,
+static void output_segment_list(OutputStream *os, AVIOContext *out, 
AVFormatContext *s,
 int representation_id, int final)
 {
+DASHContext *c = s->priv_data;
 int i, start_index = 0, start_number = 1;
 if (c->window_size) {
 start_index  = FFMAX(os->nb_segments   - c->window_size, 0);
@@ -339,7 +378,6 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 int timescale = os->ctx->streams[0]->time_base.den;
 char temp_filename_hls[1024];
 char filename_hls[1024];
-AVIOContext *out_hls = NULL;
 AVDictionary *http_opts = NULL;
 int target_duration = 0;
 int ret = 0;
@@ -352,7 +390,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
 
 set_http_options(_opts, c);
-avio_open2(_hls, temp_filename_hls, AVIO_FLAG_WRITE, NULL, 
_opts);
+dashenc_io_open(s, >m3u8_out, temp_filename_hls, _opts);
 av_dict_free(_opts);
 for (i = start_index; i < os->nb_segments; i++) {
 Segment *seg = os->segments[i];
@@ -361,15 +399,15 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 target_duration = hls_get_int_from_double(duration);
 }
 
-ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
+ff_hls_write_playlist_header(c->m3u8_out, 6, -1, target_duration,
  start_number, PLAYLIST_TYPE_NONE);
 
-ff_hls_write_init_file(out_hls, os->initfile, c->single_file,
+ff_hls_write_init_file(c->m3u8_out, os->initfile, c->single_file,
os->init_range_length, os->init_start_pos);
 
 for (i = start_index; i < os->nb_segments; i++) {
 Segment *seg = os->segments[i];
-ret = ff_hls_write_file_entry(out_hls, 0, c->single_file,
+ret = ff_hls_write_file_entry(c->m3u8_out, 0, c->single_file,
 (double) seg->duration / timescale, 0,
 seg->range_length, seg->start_pos, NULL,
 c->single_file ? os->initfile : seg->file,
@@ -380,9 +418,10 @@ static void 

[FFmpeg-devel] [PATCH 1/2] avformat/hlsenc, utils: Moved is_http_proto from hlsenc to utils for re-use

2017-12-15 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c   | 12 +++-
 libavformat/internal.h |  8 
 libavformat/utils.c|  5 +
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index e3442c3..03d54c7 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -240,15 +240,10 @@ static int mkdir_p(const char *path) {
 return ret;
 }
 
-static int is_http_proto(char *filename) {
-const char *proto = avio_find_protocol_name(filename);
-return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, 
"https")) : 0;
-}
-
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
   AVDictionary **options) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = filename ? is_http_proto(filename) : 0;
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
 int err = AVERROR_MUXER_NOT_FOUND;
 if (!*pb || !http_base_proto || !hls->http_persistent) {
 err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
@@ -264,8 +259,7 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 
 static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = filename ? is_http_proto(filename) : 0;
-
+int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
 } else {
@@ -275,7 +269,7 @@ static void hlsenc_io_close(AVFormatContext *s, AVIOContext 
**pb, char *filename
 
 static void set_http_options(AVFormatContext *s, AVDictionary **options, 
HLSContext *c)
 {
-int http_base_proto = is_http_proto(s->filename);
+int http_base_proto = ff_is_http_proto(s->filename);
 
 if (c->method) {
 av_dict_set(options, "method", c->method, 0);
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 36a5721..8f168c9 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -619,6 +619,14 @@ int ff_format_output_open(AVFormatContext *s, const char 
*url, AVDictionary **op
 void ff_format_io_close(AVFormatContext *s, AVIOContext **pb);
 
 /**
+ * Utility function to check if the file uses http or https protocol
+ *
+ * @param s AVFormatContext
+ * @param filename URL or file name to open for writing
+ */
+int ff_is_http_proto(char *filename);
+
+/**
  * Parse creation_time in AVFormatContext metadata if exists and warn if the
  * parsing fails.
  *
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 84e4920..f18a7c8 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -5459,6 +5459,11 @@ void ff_format_io_close(AVFormatContext *s, AVIOContext 
**pb)
 *pb = NULL;
 }
 
+int ff_is_http_proto(char *filename) {
+const char *proto = avio_find_protocol_name(filename);
+return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, 
"https")) : 0;
+}
+
 int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, 
int return_seconds)
 {
 AVDictionaryEntry *entry;
-- 
1.9.1

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


[FFmpeg-devel] [PATCH] avformat/hlsenc: Minor fix for persistent http connection of init fmp4

2017-12-15 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index fdf614b..0e2f412 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1787,7 +1787,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 vs->init_range_length = range_length;
 avio_open_dyn_buf(>pb);
 vs->packets_written = 0;
-ff_format_io_close(s, >out);
 hlsenc_io_close(s, >out, vs->base_output_dirname);
 } else {
 hlsenc_io_close(s, >pb, oc->filename);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 2/3] avformat/hlsenc: Handle NULL input in IO open and close utility functions

2017-12-14 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 30d0285..af9d949 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -246,7 +246,7 @@ static int is_http_proto(char *filename) {
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
   AVDictionary **options) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = is_http_proto(filename);
+int http_base_proto = filename ? is_http_proto(filename) : 0;
 int err = AVERROR_MUXER_NOT_FOUND;
 if (!*pb || !http_base_proto || !hls->http_persistent) {
 err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
@@ -262,7 +262,7 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 
 static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = is_http_proto(filename);
+int http_base_proto = filename ? is_http_proto(filename) : 0;
 
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 3/3] avformat/hlsenc: Extend persistent http connections to playlists

2017-12-14 Thread Karthick J
From: Karthick Jeyapal 

Before this patch persistent http connections would work only for media 
segments.
The playlists were still opening a new connection everytime.
This patch extends persistent http connections to playlists as well.
---
 libavformat/hlsenc.c | 56 +---
 1 file changed, 27 insertions(+), 29 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index af9d949..e3442c3 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -203,6 +203,8 @@ typedef struct HLSContext {
 char *master_pl_name;
 unsigned int master_publish_rate;
 int http_persistent;
+AVIOContext *m3u8_out;
+AVIOContext *sub_m3u8_out;
 } HLSContext;
 
 static int mkdir_p(const char *path) {
@@ -1085,7 +1087,6 @@ static int create_master_playlist(AVFormatContext *s,
 HLSContext *hls = s->priv_data;
 VariantStream *vs;
 AVStream *vid_st, *aud_st;
-AVIOContext *master_pb = 0;
 AVDictionary *options = NULL;
 unsigned int i, j;
 int m3u8_name_size, ret, bandwidth;
@@ -1106,8 +1107,7 @@ static int create_master_playlist(AVFormatContext *s,
 
 set_http_options(s, , hls);
 
-ret = s->io_open(s, _pb, hls->master_m3u8_url, AVIO_FLAG_WRITE,\
- );
+ret = hlsenc_io_open(s, >m3u8_out, hls->master_m3u8_url, );
 av_dict_free();
 if (ret < 0) {
 av_log(NULL, AV_LOG_ERROR, "Failed to open master play list file 
'%s'\n",
@@ -1115,7 +1115,7 @@ static int create_master_playlist(AVFormatContext *s,
 goto fail;
 }
 
-ff_hls_write_playlist_version(master_pb, hls->version);
+ff_hls_write_playlist_version(hls->m3u8_out, hls->version);
 
 /* For variant streams with video add #EXT-X-STREAM-INF tag with 
attributes*/
 for (i = 0; i < hls->nb_varstreams; i++) {
@@ -1156,7 +1156,7 @@ static int create_master_playlist(AVFormatContext *s,
 bandwidth += aud_st->codecpar->bit_rate;
 bandwidth += bandwidth / 10;
 
-ff_hls_write_stream_info(vid_st, master_pb, bandwidth, m3u8_rel_name);
+ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, 
m3u8_rel_name);
 
 av_freep(_rel_name);
 }
@@ -1164,7 +1164,7 @@ fail:
 if(ret >=0)
 hls->master_m3u8_created = 1;
 av_freep(_rel_name);
-ff_format_io_close(s, _pb);
+hlsenc_io_close(s, >m3u8_out, hls->master_m3u8_url);
 return ret;
 }
 
@@ -1174,8 +1174,6 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 HLSSegment *en;
 int target_duration = 0;
 int ret = 0;
-AVIOContext *out = NULL;
-AVIOContext *sub_out = NULL;
 char temp_filename[1024];
 int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - 
vs->nb_entries);
 const char *proto = avio_find_protocol_name(s->filename);
@@ -1207,7 +1205,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 
 set_http_options(s, , hls);
 snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : 
"%s", vs->m3u8_name);
-if ((ret = s->io_open(s, , temp_filename, AVIO_FLAG_WRITE, )) 
< 0)
+if ((ret = hlsenc_io_open(s, >m3u8_out, temp_filename, )) < 0)
 goto fail;
 
 for (en = vs->segments; en; en = en->next) {
@@ -1216,67 +1214,67 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 }
 
 vs->discontinuity_set = 0;
-ff_hls_write_playlist_header(out, hls->version, hls->allowcache,
+ff_hls_write_playlist_header(hls->m3u8_out, hls->version, hls->allowcache,
  target_duration, sequence, hls->pl_type);
 
 if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && 
vs->discontinuity_set==0 ){
-avio_printf(out, "#EXT-X-DISCONTINUITY\n");
+avio_printf(hls->m3u8_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");
+avio_printf(hls->m3u8_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))) {
-avio_printf(out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", 
en->key_uri);
+avio_printf(hls->m3u8_out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", 
en->key_uri);
 if (*en->iv_string)
-avio_printf(out, ",IV=0x%s", en->iv_string);
-avio_printf(out, "\n");
+avio_printf(hls->m3u8_out, ",IV=0x%s", en->iv_string);
+avio_printf(hls->m3u8_out, "\n");
 key_uri = en->key_uri;
 iv_string = en->iv_string;
 }
 
 if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
-

[FFmpeg-devel] [PATCH v2 1/3] avformat/hlsenc: Call avio_flush during persistent http connections

2017-12-14 Thread Karthick J
From: Karthick Jeyapal 

Since close is not called, during http persistent connection,
flush needs to be called so that output is written on time.
---
 libavformat/hlsenc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index fdf614b..30d0285 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -266,6 +266,8 @@ static void hlsenc_io_close(AVFormatContext *s, AVIOContext 
**pb, char *filename
 
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
+} else {
+avio_flush(*pb);
 }
 }
 
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 3/3] avformat/hlsenc: Extend persistent http connections to playlists

2017-11-30 Thread Karthick J
From: Karthick Jeyapal 

Before this patch persistent http connections would work only for media 
segments.
The playlists were still opening a new connection everytime.
This patch extends persistent http connections to playlists as well.
---
 libavformat/hlsenc.c | 46 ++
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index ff982c5..350836d 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -201,6 +201,8 @@ typedef struct HLSContext {
 char *master_pl_name;
 unsigned int master_publish_rate;
 int http_persistent;
+AVIOContext *m3u8_out;
+AVIOContext *sub_m3u8_out;
 } HLSContext;
 
 static int mkdir_p(const char *path) {
@@ -1081,7 +1083,6 @@ static int create_master_playlist(AVFormatContext *s,
 HLSContext *hls = s->priv_data;
 VariantStream *vs;
 AVStream *vid_st, *aud_st;
-AVIOContext *master_pb = 0;
 AVDictionary *options = NULL;
 unsigned int i, j;
 int m3u8_name_size, ret, bandwidth;
@@ -1102,8 +1103,7 @@ static int create_master_playlist(AVFormatContext *s,
 
 set_http_options(s, , hls);
 
-ret = s->io_open(s, _pb, hls->master_m3u8_url, AVIO_FLAG_WRITE,\
- );
+ret = hlsenc_io_open(s, >m3u8_out, hls->master_m3u8_url, );
 av_dict_free();
 if (ret < 0) {
 av_log(NULL, AV_LOG_ERROR, "Failed to open master play list file 
'%s'\n",
@@ -,7 +,7 @@ static int create_master_playlist(AVFormatContext *s,
 goto fail;
 }
 
-ff_hls_write_playlist_version(master_pb, hls->version);
+ff_hls_write_playlist_version(hls->m3u8_out, hls->version);
 
 /* For variant streams with video add #EXT-X-STREAM-INF tag with 
attributes*/
 for (i = 0; i < hls->nb_varstreams; i++) {
@@ -1152,7 +1152,7 @@ static int create_master_playlist(AVFormatContext *s,
 bandwidth += aud_st->codecpar->bit_rate;
 bandwidth += bandwidth / 10;
 
-ff_hls_write_stream_info(vid_st, master_pb, bandwidth, m3u8_rel_name);
+ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, 
m3u8_rel_name);
 
 av_freep(_rel_name);
 }
@@ -1160,7 +1160,7 @@ fail:
 if(ret >=0)
 hls->master_m3u8_created = 1;
 av_freep(_rel_name);
-ff_format_io_close(s, _pb);
+hlsenc_io_close(s, >m3u8_out, hls->master_m3u8_url);
 return ret;
 }
 
@@ -1170,8 +1170,6 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 HLSSegment *en;
 int target_duration = 0;
 int ret = 0;
-AVIOContext *out = NULL;
-AVIOContext *sub_out = NULL;
 char temp_filename[1024];
 int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - 
vs->nb_entries);
 const char *proto = avio_find_protocol_name(s->filename);
@@ -1203,7 +1201,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 
 set_http_options(s, , hls);
 snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : 
"%s", vs->m3u8_name);
-if ((ret = s->io_open(s, , temp_filename, AVIO_FLAG_WRITE, )) 
< 0)
+if ((ret = hlsenc_io_open(s, >m3u8_out, temp_filename, )) < 0)
 goto fail;
 
 for (en = vs->segments; en; en = en->next) {
@@ -1212,33 +1210,33 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 }
 
 vs->discontinuity_set = 0;
-ff_hls_write_playlist_header(out, hls->version, hls->allowcache,
+ff_hls_write_playlist_header(hls->m3u8_out, hls->version, hls->allowcache,
  target_duration, sequence, hls->pl_type);
 
 if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && 
vs->discontinuity_set==0 ){
-avio_printf(out, "#EXT-X-DISCONTINUITY\n");
+avio_printf(hls->m3u8_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");
+avio_printf(hls->m3u8_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))) {
-avio_printf(out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", 
en->key_uri);
+avio_printf(hls->m3u8_out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", 
en->key_uri);
 if (*en->iv_string)
-avio_printf(out, ",IV=0x%s", en->iv_string);
-avio_printf(out, "\n");
+avio_printf(hls->m3u8_out, ",IV=0x%s", en->iv_string);
+avio_printf(hls->m3u8_out, "\n");
 key_uri = en->key_uri;
 iv_string = en->iv_string;
 }
 
 if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
-

[FFmpeg-devel] [PATCH 1/3] avformat/hlsenc: Call avio_flush during persistent http connections

2017-11-30 Thread Karthick J
From: Karthick Jeyapal 

Since close is not called, during http persistent connection,
flush needs to be called so that output is written on time.
---
 libavformat/hlsenc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index cdfbf45..9048cb2 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -262,6 +262,8 @@ static void hlsenc_io_close(AVFormatContext *s, AVIOContext 
**pb, char *filename
 
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
+} else {
+avio_flush(*pb);
 }
 }
 
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/3] avformat/hlsenc: Handle NULL input in IO open and close utility functions

2017-11-30 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 9048cb2..ff982c5 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -244,7 +244,7 @@ static int is_http_proto(char *filename) {
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
   AVDictionary **options) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = is_http_proto(filename);
+int http_base_proto = filename ? is_http_proto(filename) : 0;
 int err;
 if (!*pb || !http_base_proto || !hls->http_persistent) {
 err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
@@ -258,7 +258,7 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext 
**pb, char *filename,
 
 static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
 HLSContext *hls = s->priv_data;
-int http_base_proto = is_http_proto(filename);
+int http_base_proto = filename ? is_http_proto(filename) : 0;
 
 if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
 ff_format_io_close(s, pb);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v2 2/2] avformat/dashenc: Option to generate hls playlist as well

2017-11-29 Thread Karthick J
This is to take full advantage of Common Media Application Format.
Now server can generate one content and serve both HLS and DASH players.
---
 doc/muxers.texi   |   3 ++
 libavformat/Makefile  |   2 +-
 libavformat/dashenc.c | 110 +++---
 3 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 8ec48c2..3d0c7bf 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -249,6 +249,9 @@ DASH-templated name to used for the media segments. Default 
is "chunk-stream$Rep
 URL of the page that will return the UTC timestamp in ISO format. Example: 
"https://time.akamai.com/?iso;
 @item -http_user_agent @var{user_agent}
 Override User-Agent field in HTTP header. 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 -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/Makefile b/libavformat/Makefile
index fd8b9f9..4bffdf2 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -135,7 +135,7 @@ OBJS-$(CONFIG_CONCAT_DEMUXER)+= concatdec.o
 OBJS-$(CONFIG_CRC_MUXER) += crcenc.o
 OBJS-$(CONFIG_DATA_DEMUXER)  += rawdec.o
 OBJS-$(CONFIG_DATA_MUXER)+= rawenc.o
-OBJS-$(CONFIG_DASH_MUXER)+= dash.o dashenc.o
+OBJS-$(CONFIG_DASH_MUXER)+= dash.o dashenc.o hlsplaylist.o
 OBJS-$(CONFIG_DASH_DEMUXER)  += dash.o dashdec.o
 OBJS-$(CONFIG_DAUD_DEMUXER)  += dauddec.o
 OBJS-$(CONFIG_DAUD_MUXER)+= daudenc.o
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 0fee3cd..1783675 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -36,6 +36,7 @@
 #include "avc.h"
 #include "avformat.h"
 #include "avio_internal.h"
+#include "hlsplaylist.h"
 #include "internal.h"
 #include "isom.h"
 #include "os_support.h"
@@ -101,6 +102,8 @@ typedef struct DASHContext {
 const char *media_seg_name;
 const char *utc_timing_url;
 const char *user_agent;
+int hls_playlist;
+int master_playlist_created;
 } DASHContext;
 
 static struct codec_string {
@@ -217,6 +220,14 @@ static void set_http_options(AVDictionary **options, 
DASHContext *c)
 av_dict_set(options, "user_agent", c->user_agent, 0);
 }
 
+static void get_hls_playlist_name(char *playlist_name, int string_size,
+  const char *base_url, int id) {
+if (base_url)
+snprintf(playlist_name, string_size, "%smedia_%d.m3u8", base_url, id);
+else
+snprintf(playlist_name, string_size, "media_%d.m3u8", id);
+}
+
 static int flush_init_segment(AVFormatContext *s, OutputStream *os)
 {
 DASHContext *c = s->priv_data;
@@ -262,7 +273,8 @@ static void dash_free(AVFormatContext *s)
 av_freep(>streams);
 }
 
-static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c)
+static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c,
+int representation_id, int final)
 {
 int i, start_index = 0, start_number = 1;
 if (c->window_size) {
@@ -322,6 +334,55 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 }
 avio_printf(out, "\t\t\t\t\n");
 }
+if (c->hls_playlist && start_index < os->nb_segments)
+{
+int timescale = os->ctx->streams[0]->time_base.den;
+char temp_filename_hls[1024];
+char filename_hls[1024];
+AVIOContext *out_hls = NULL;
+AVDictionary *http_opts = NULL;
+int target_duration = 0;
+const char *proto = avio_find_protocol_name(c->dirname);
+int use_rename = proto && !strcmp(proto, "file");
+
+get_hls_playlist_name(filename_hls, sizeof(filename_hls),
+  c->dirname, representation_id);
+
+snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
+
+set_http_options(_opts, c);
+avio_open2(_hls, temp_filename_hls, AVIO_FLAG_WRITE, NULL, 
_opts);
+av_dict_free(_opts);
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+double duration = (double) seg->duration / timescale;
+if (target_duration <= duration)
+target_duration = hls_get_int_from_double(duration);
+}
+
+ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
+ start_number, PLAYLIST_TYPE_NONE);
+
+

[FFmpeg-devel] [PATCH v2 1/2] avformat/hlsenc: Refactored 'get_int_from_double' function to allow reuse

2017-11-29 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c  | 7 +--
 libavformat/hlsplaylist.h | 5 +
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index f63b08d..cdfbf45 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -203,11 +203,6 @@ typedef struct HLSContext {
 int http_persistent;
 } HLSContext;
 
-static int get_int_from_double(double val)
-{
-return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
-}
-
 static int mkdir_p(const char *path) {
 int ret = 0;
 char *temp = av_strdup(path);
@@ -1211,7 +1206,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 
 for (en = vs->segments; en; en = en->next) {
 if (target_duration <= en->duration)
-target_duration = get_int_from_double(en->duration);
+target_duration = hls_get_int_from_double(en->duration);
 }
 
 vs->discontinuity_set = 0;
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index fd36c7e..68ef8d4 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -32,6 +32,11 @@ typedef enum {
 PLAYLIST_TYPE_NB,
 } PlaylistType;
 
+static inline int hls_get_int_from_double(double val)
+{
+return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
+}
+
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
   int bandwidth, char *filename);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 1/2] avformat/hlsenc: Refactored 'get_int_from_double' function to allow reuse

2017-11-29 Thread Karthick J
From: Karthick Jeyapal 

---
 libavformat/hlsenc.c  | 7 +--
 libavformat/hlsplaylist.h | 5 +
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index f63b08d..cdfbf45 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -203,11 +203,6 @@ typedef struct HLSContext {
 int http_persistent;
 } HLSContext;
 
-static int get_int_from_double(double val)
-{
-return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
-}
-
 static int mkdir_p(const char *path) {
 int ret = 0;
 char *temp = av_strdup(path);
@@ -1211,7 +1206,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 
 for (en = vs->segments; en; en = en->next) {
 if (target_duration <= en->duration)
-target_duration = get_int_from_double(en->duration);
+target_duration = hls_get_int_from_double(en->duration);
 }
 
 vs->discontinuity_set = 0;
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index fd36c7e..68ef8d4 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -32,6 +32,11 @@ typedef enum {
 PLAYLIST_TYPE_NB,
 } PlaylistType;
 
+static inline int hls_get_int_from_double(double val)
+{
+return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
+}
+
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
   int bandwidth, char *filename);
-- 
1.9.1

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


[FFmpeg-devel] [PATCH 2/2] avformat/dashenc: Option to generate hls playlist as well

2017-11-29 Thread Karthick J
This is to take full advantage of Common Media Application Format.
Now server can generate one content and serve both HLS and DASH players.
---
 doc/muxers.texi   |   3 ++
 libavformat/Makefile  |   2 +-
 libavformat/dashenc.c | 103 --
 3 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 8ec48c2..3d0c7bf 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -249,6 +249,9 @@ DASH-templated name to used for the media segments. Default 
is "chunk-stream$Rep
 URL of the page that will return the UTC timestamp in ISO format. Example: 
"https://time.akamai.com/?iso;
 @item -http_user_agent @var{user_agent}
 Override User-Agent field in HTTP header. 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 -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/Makefile b/libavformat/Makefile
index fd8b9f9..4bffdf2 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -135,7 +135,7 @@ OBJS-$(CONFIG_CONCAT_DEMUXER)+= concatdec.o
 OBJS-$(CONFIG_CRC_MUXER) += crcenc.o
 OBJS-$(CONFIG_DATA_DEMUXER)  += rawdec.o
 OBJS-$(CONFIG_DATA_MUXER)+= rawenc.o
-OBJS-$(CONFIG_DASH_MUXER)+= dash.o dashenc.o
+OBJS-$(CONFIG_DASH_MUXER)+= dash.o dashenc.o hlsplaylist.o
 OBJS-$(CONFIG_DASH_DEMUXER)  += dash.o dashdec.o
 OBJS-$(CONFIG_DAUD_DEMUXER)  += dauddec.o
 OBJS-$(CONFIG_DAUD_MUXER)+= daudenc.o
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 0fee3cd..efc2012 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -36,6 +36,7 @@
 #include "avc.h"
 #include "avformat.h"
 #include "avio_internal.h"
+#include "hlsplaylist.h"
 #include "internal.h"
 #include "isom.h"
 #include "os_support.h"
@@ -101,6 +102,8 @@ typedef struct DASHContext {
 const char *media_seg_name;
 const char *utc_timing_url;
 const char *user_agent;
+int hls_playlist;
+int master_playlist_created;
 } DASHContext;
 
 static struct codec_string {
@@ -217,6 +220,14 @@ static void set_http_options(AVDictionary **options, 
DASHContext *c)
 av_dict_set(options, "user_agent", c->user_agent, 0);
 }
 
+static void get_hls_playlist_name(char *playlist_name, int string_size,
+  const char *base_url, int id) {
+if (base_url)
+snprintf(playlist_name, string_size, "%smedia_%d.m3u8", base_url, id);
+else
+snprintf(playlist_name, string_size, "media_%d.m3u8", id);
+}
+
 static int flush_init_segment(AVFormatContext *s, OutputStream *os)
 {
 DASHContext *c = s->priv_data;
@@ -262,7 +273,8 @@ static void dash_free(AVFormatContext *s)
 av_freep(>streams);
 }
 
-static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c)
+static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c,
+int representation_id, int final)
 {
 int i, start_index = 0, start_number = 1;
 if (c->window_size) {
@@ -322,6 +334,55 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 }
 avio_printf(out, "\t\t\t\t\n");
 }
+if (c->hls_playlist && start_index < os->nb_segments)
+{
+int timescale = os->ctx->streams[0]->time_base.den;
+char temp_filename_hls[1024];
+char filename_hls[1024];
+AVIOContext *out_hls = NULL;
+AVDictionary *http_opts = NULL;
+int target_duration = 0;
+const char *proto = avio_find_protocol_name(c->dirname);
+int use_rename = proto && !strcmp(proto, "file");
+
+get_hls_playlist_name(filename_hls, sizeof(filename_hls),
+  c->dirname, representation_id);
+
+snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
+
+set_http_options(_opts, c);
+avio_open2(_hls, temp_filename_hls, AVIO_FLAG_WRITE, NULL, 
_opts);
+av_dict_free(_opts);
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+double duration = (double) seg->duration / timescale;
+if (target_duration <= duration)
+target_duration = hls_get_int_from_double(duration);
+}
+
+ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
+ start_number, PLAYLIST_TYPE_NONE);
+
+

[FFmpeg-devel] [PATCH v6 2/2] avformat/dashenc: Option to generate hls playlist as well

2017-11-29 Thread Karthick J
This is to take full advantage of Common Media Application Format.
Now server can generate one content and serve both HLS and DASH players.
---
 doc/muxers.texi   |   3 ++
 libavformat/Makefile  |   2 +-
 libavformat/dashenc.c | 103 --
 3 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 8ec48c2..3d0c7bf 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -249,6 +249,9 @@ DASH-templated name to used for the media segments. Default 
is "chunk-stream$Rep
 URL of the page that will return the UTC timestamp in ISO format. Example: 
"https://time.akamai.com/?iso;
 @item -http_user_agent @var{user_agent}
 Override User-Agent field in HTTP header. 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 -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/Makefile b/libavformat/Makefile
index fd8b9f9..4bffdf2 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -135,7 +135,7 @@ OBJS-$(CONFIG_CONCAT_DEMUXER)+= concatdec.o
 OBJS-$(CONFIG_CRC_MUXER) += crcenc.o
 OBJS-$(CONFIG_DATA_DEMUXER)  += rawdec.o
 OBJS-$(CONFIG_DATA_MUXER)+= rawenc.o
-OBJS-$(CONFIG_DASH_MUXER)+= dash.o dashenc.o
+OBJS-$(CONFIG_DASH_MUXER)+= dash.o dashenc.o hlsplaylist.o
 OBJS-$(CONFIG_DASH_DEMUXER)  += dash.o dashdec.o
 OBJS-$(CONFIG_DAUD_DEMUXER)  += dauddec.o
 OBJS-$(CONFIG_DAUD_MUXER)+= daudenc.o
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 0fee3cd..ee9dc85 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -36,6 +36,7 @@
 #include "avc.h"
 #include "avformat.h"
 #include "avio_internal.h"
+#include "hlsplaylist.h"
 #include "internal.h"
 #include "isom.h"
 #include "os_support.h"
@@ -101,6 +102,8 @@ typedef struct DASHContext {
 const char *media_seg_name;
 const char *utc_timing_url;
 const char *user_agent;
+int hls_playlist;
+int master_playlist_created;
 } DASHContext;
 
 static struct codec_string {
@@ -217,6 +220,14 @@ static void set_http_options(AVDictionary **options, 
DASHContext *c)
 av_dict_set(options, "user_agent", c->user_agent, 0);
 }
 
+static void get_hls_playlist_name(char *playlist_name, int string_size,
+  const char *base_url, int id) {
+if (base_url)
+snprintf(playlist_name, string_size, "%smedia_%d.m3u8", base_url, id);
+else
+snprintf(playlist_name, string_size, "media_%d.m3u8", id);
+}
+
 static int flush_init_segment(AVFormatContext *s, OutputStream *os)
 {
 DASHContext *c = s->priv_data;
@@ -262,7 +273,8 @@ static void dash_free(AVFormatContext *s)
 av_freep(>streams);
 }
 
-static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c)
+static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c,
+int representation_id, int final)
 {
 int i, start_index = 0, start_number = 1;
 if (c->window_size) {
@@ -322,6 +334,55 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
 }
 avio_printf(out, "\t\t\t\t\n");
 }
+if (c->hls_playlist && start_index < os->nb_segments)
+{
+int timescale = os->ctx->streams[0]->time_base.den;
+char temp_filename_hls[1024];
+char filename_hls[1024];
+AVIOContext *out_hls = NULL;
+AVDictionary *http_opts = NULL;
+int target_duration = 0;
+const char *proto = avio_find_protocol_name(c->dirname);
+int use_rename = proto && !strcmp(proto, "file");
+
+get_hls_playlist_name(filename_hls, sizeof(filename_hls),
+  c->dirname, representation_id);
+
+snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? 
"%s.tmp" : "%s", filename_hls);
+
+set_http_options(_opts, c);
+avio_open2(_hls, temp_filename_hls, AVIO_FLAG_WRITE, NULL, 
_opts);
+av_dict_free(_opts);
+for (i = start_index; i < os->nb_segments; i++) {
+Segment *seg = os->segments[i];
+if (target_duration < seg->duration)
+target_duration = seg->duration;
+}
+target_duration = lrint((double) target_duration / timescale);
+
+ff_hls_write_playlist_header(out_hls, 6, -1, target_duration,
+ start_number, PLAYLIST_TYPE_NONE);
+
+ff_hls_write_init_file(out_hls, 

[FFmpeg-devel] [PATCH v6 1/2] avformat/hlsenc: Modularized playlist creation to allow reuse

2017-11-29 Thread Karthick J
---
 libavformat/Makefile  |   2 +-
 libavformat/hlsenc.c  | 115 +++---
 libavformat/hlsplaylist.c | 138 ++
 libavformat/hlsplaylist.h |  51 +
 4 files changed, 211 insertions(+), 95 deletions(-)
 create mode 100644 libavformat/hlsplaylist.c
 create mode 100644 libavformat/hlsplaylist.h

diff --git a/libavformat/Makefile b/libavformat/Makefile
index b1e7b19..fd8b9f9 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -215,7 +215,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o
 OBJS-$(CONFIG_HEVC_DEMUXER)  += hevcdec.o rawdec.o
 OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o
 OBJS-$(CONFIG_HLS_DEMUXER)   += hls.o
-OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o
+OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o
 OBJS-$(CONFIG_HNM_DEMUXER)   += hnm.o
 OBJS-$(CONFIG_ICO_DEMUXER)   += icodec.o
 OBJS-$(CONFIG_ICO_MUXER) += icoenc.o
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index d5c732f..f63b08d 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -46,6 +46,7 @@
 #include "avformat.h"
 #include "avio_internal.h"
 #include "http.h"
+#include "hlsplaylist.h"
 #include "internal.h"
 #include "os_support.h"
 
@@ -97,13 +98,6 @@ typedef enum {
 SEGMENT_TYPE_FMP4,
 } SegmentType;
 
-typedef enum {
-PLAYLIST_TYPE_NONE,
-PLAYLIST_TYPE_EVENT,
-PLAYLIST_TYPE_VOD,
-PLAYLIST_TYPE_NB,
-} PlaylistType;
-
 typedef struct VariantStream {
 unsigned number;
 int64_t sequence;
@@ -1055,19 +1049,6 @@ static void hls_free_segments(HLSSegment *p)
 }
 }
 
-static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int 
version,
-  int target_duration, int64_t sequence)
-{
-avio_printf(out, "#EXTM3U\n");
-avio_printf(out, "#EXT-X-VERSION:%d\n", version);
-if (hls->allowcache == 0 || hls->allowcache == 1) {
-avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? 
"NO" : "YES");
-}
-avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
-avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
-av_log(hls, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
-}
-
 static void hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
 {
 size_t len = strlen(oc->filename);
@@ -1133,8 +1114,7 @@ static int create_master_playlist(AVFormatContext *s,
 goto fail;
 }
 
-avio_printf(master_pb, "#EXTM3U\n");
-avio_printf(master_pb, "#EXT-X-VERSION:%d\n", hls->version);
+ff_hls_write_playlist_version(master_pb, hls->version);
 
 /* For variant streams with video add #EXT-X-STREAM-INF tag with 
attributes*/
 for (i = 0; i < hls->nb_varstreams; i++) {
@@ -1175,18 +1155,7 @@ static int create_master_playlist(AVFormatContext *s,
 bandwidth += aud_st->codecpar->bit_rate;
 bandwidth += bandwidth / 10;
 
-if (!bandwidth) {
-av_log(NULL, AV_LOG_WARNING,
-"Bandwidth info not available, set audio and video 
bitrates\n");
-av_freep(_rel_name);
-continue;
-}
-
-avio_printf(master_pb, "#EXT-X-STREAM-INF:BANDWIDTH=%d", bandwidth);
-if (vid_st && vid_st->codecpar->width > 0 && vid_st->codecpar->height 
> 0)
-avio_printf(master_pb, ",RESOLUTION=%dx%d", 
vid_st->codecpar->width,
-vid_st->codecpar->height);
-avio_printf(master_pb, "\n%s\n\n", m3u8_rel_name);
+ff_hls_write_stream_info(vid_st, master_pb, bandwidth, m3u8_rel_name);
 
 av_freep(_rel_name);
 }
@@ -1215,6 +1184,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 char *iv_string = NULL;
 AVDictionary *options = NULL;
 double prog_date_time = vs->initial_prog_date_time;
+double *prog_date_time_p = (hls->flags & HLS_PROGRAM_DATE_TIME) ? 
_date_time : NULL;
 int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size 
> 0);
 
 hls->version = 3;
@@ -1245,12 +1215,8 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 }
 
 vs->discontinuity_set = 0;
-write_m3u8_head_block(hls, out, hls->version, target_duration, sequence);
-if (hls->pl_type == PLAYLIST_TYPE_EVENT) {
-avio_printf(out, "#EXT-X-PLAYLIST-TYPE:EVENT\n");
-} else if (hls->pl_type == PLAYLIST_TYPE_VOD) {
-avio_printf(out, "#EXT-X-PLAYLIST-TYPE:VOD\n");
-}
+ff_hls_write_playlist_header(out, hls->version, hls->allowcache,
+ target_duration, sequence, hls->pl_type);
 
 if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && 
vs->discontinuity_set==0 ){
 avio_printf(out, "#EXT-X-DISCONTINUITY\n");
@@ -1270,74 +1236,35 @@ static int hls_window(AVFormatContext *s, int last, 

[FFmpeg-devel] [PATCH v3 3/3] libavformat/hlsenc: Persistent HTTP connections supported as an option

2017-11-28 Thread Karthick J
---
 doc/muxers.texi  |  3 +++
 libavformat/hlsenc.c | 48 +---
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 9d9ca31..8ec48c2 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -854,6 +854,9 @@ ffmpeg -re -i in.ts -f hls -master_pl_name master.m3u8 \
 This example creates HLS master playlist with name master.m3u8 and keep
 publishing it repeatedly every after 30 segments i.e. every after 60s.
 
+@item http_persistent
+Use persistent HTTP connections. Applicable only for HTTP output.
+
 @end table
 
 @anchor{ico}
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 6997a5c..d5c732f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -45,6 +45,7 @@
 
 #include "avformat.h"
 #include "avio_internal.h"
+#include "http.h"
 #include "internal.h"
 #include "os_support.h"
 
@@ -205,6 +206,7 @@ typedef struct HLSContext {
 char *var_stream_map; /* user specified variant stream map string */
 char *master_pl_name;
 unsigned int master_publish_rate;
+int http_persistent;
 } HLSContext;
 
 static int get_int_from_double(double val)
@@ -245,10 +247,38 @@ static int mkdir_p(const char *path) {
 return ret;
 }
 
+static int is_http_proto(char *filename) {
+const char *proto = avio_find_protocol_name(filename);
+return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, 
"https")) : 0;
+}
+
+static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
+  AVDictionary **options) {
+HLSContext *hls = s->priv_data;
+int http_base_proto = is_http_proto(filename);
+int err;
+if (!*pb || !http_base_proto || !hls->http_persistent) {
+err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
+} else {
+URLContext *http_url_context = ffio_geturlcontext(*pb);
+av_assert0(http_url_context);
+err = ff_http_do_new_request(http_url_context, filename);
+}
+return err;
+}
+
+static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char 
*filename) {
+HLSContext *hls = s->priv_data;
+int http_base_proto = is_http_proto(filename);
+
+if (!http_base_proto || !hls->http_persistent || hls->key_info_file || 
hls->encrypt) {
+ff_format_io_close(s, pb);
+}
+}
+
 static void set_http_options(AVFormatContext *s, AVDictionary **options, 
HLSContext *c)
 {
-const char *proto = avio_find_protocol_name(s->filename);
-int http_base_proto = proto ? (!av_strcasecmp(proto, "http") || 
!av_strcasecmp(proto, "https")) : 0;
+int http_base_proto = is_http_proto(s->filename);
 
 if (c->method) {
 av_dict_set(options, "method", c->method, 0);
@@ -258,6 +288,8 @@ static void set_http_options(AVFormatContext *s, 
AVDictionary **options, HLSCont
 }
 if (c->user_agent)
 av_dict_set(options, "user_agent", c->user_agent, 0);
+if (c->http_persistent)
+av_dict_set_int(options, "multiple_requests", 1, 0);
 
 }
 
@@ -1437,17 +1469,17 @@ static int hls_start(AVFormatContext *s, VariantStream 
*vs)
 err = AVERROR(ENOMEM);
 goto fail;
 }
-err = s->io_open(s, >pb, filename, AVIO_FLAG_WRITE, );
+err = hlsenc_io_open(s, >pb, filename, );
 av_free(filename);
 av_dict_free();
 if (err < 0)
 return err;
 } else
-if ((err = s->io_open(s, >pb, oc->filename, AVIO_FLAG_WRITE, 
)) < 0)
+if ((err = hlsenc_io_open(s, >pb, oc->filename, )) < 0)
 goto fail;
 if (vs->vtt_basename) {
 set_http_options(s, , c);
-if ((err = s->io_open(s, _oc->pb, vtt_oc->filename, 
AVIO_FLAG_WRITE, )) < 0)
+if ((err = hlsenc_io_open(s, _oc->pb, vtt_oc->filename, )) 
< 0)
 goto fail;
 }
 av_dict_free();
@@ -2165,11 +2197,12 @@ static int hls_write_packet(AVFormatContext *s, 
AVPacket *pkt)
 avio_open_dyn_buf(>pb);
 vs->packets_written = 0;
 ff_format_io_close(s, >out);
+hlsenc_io_close(s, >out, vs->base_output_dirname);
 } else {
-ff_format_io_close(s, >pb);
+hlsenc_io_close(s, >pb, oc->filename);
 }
 if (vs->vtt_avf) {
-ff_format_io_close(s, >vtt_avf->pb);
+hlsenc_io_close(s, >vtt_avf->pb, vs->vtt_avf->filename);
 }
 }
 if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {
@@ -2355,6 +2388,7 @@ static const AVOption options[] = {
 {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), 
AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,E},
 {"master_pl_name", "Create HLS master playlist with this name", 
OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,E},
 {"master_pl_publish_rate", "Publish master play list every after this many 
segment intervals", 

[FFmpeg-devel] [PATCH v3 2/3] libavformat/http: Handled multiple_requests option during write

2017-11-28 Thread Karthick J
---
 libavformat/http.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libavformat/http.c b/libavformat/http.c
index 056d5f6..cf86adc 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -171,6 +171,7 @@ static int http_connect(URLContext *h, const char *path, 
const char *local_path,
 const char *hoststr, const char *auth,
 const char *proxyauth, int *new_location);
 static int http_read_header(URLContext *h, int *new_location);
+static int http_shutdown(URLContext *h, int flags);
 
 void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
 {
@@ -306,6 +307,11 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
 AVDictionary *options = NULL;
 int ret;
 
+ret = http_shutdown(h, h->flags);
+if (ret < 0)
+return ret;
+
+s->end_chunked_post = 0;
 s->chunkend  = 0;
 s->off   = 0;
 s->icy_data_read = 0;
-- 
1.9.1

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


[FFmpeg-devel] [PATCH v3 1/3] libavformat/avio: Utility function to return URLContext

2017-11-28 Thread Karthick J
---
 libavformat/avio_internal.h |  8 
 libavformat/aviobuf.c   | 13 +
 2 files changed, 21 insertions(+)

diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index c01835d..04c1ad5 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -133,6 +133,14 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int 
max_packet_size);
 int ffio_fdopen(AVIOContext **s, URLContext *h);
 
 /**
+ * Return the URLContext associated with the AVIOContext
+ *
+ * @param s IO context
+ * @return pointer to URLContext or NULL.
+ */
+URLContext *ffio_geturlcontext(AVIOContext *s);
+
+/**
  * Open a write-only fake memory stream. The written data is not stored
  * anywhere - this is only used for measuring the amount of data
  * written.
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 3b4c843..86eb657 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -980,6 +980,19 @@ fail:
 return AVERROR(ENOMEM);
 }
 
+URLContext* ffio_geturlcontext(AVIOContext *s)
+{
+AVIOInternal *internal;
+if (!s)
+return NULL;
+
+internal = s->opaque;
+if (internal && s->read_packet == io_read_packet)
+return internal->h;
+else
+return NULL;
+}
+
 int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
 {
 uint8_t *buffer;
-- 
1.9.1

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


  1   2   >