[FFmpeg-devel] [PATCH v4 1/2] lavf/hls: refactoring of read_header

2017-12-03 Thread Rainer Hochecker
---
 libavformat/hls.c | 208 +++---
 1 file changed, 119 insertions(+), 89 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index ab6ff187a6..3c2c720abe 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -314,6 +314,8 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->is_id3_timestamped = -1;
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
+pls->index = c->n_playlists;
+pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
 }
@@ -1670,6 +1672,121 @@ static int hls_close(AVFormatContext *s)
 return 0;
 }
 
+static int init_playlist(HLSContext *c, struct playlist *pls)
+{
+AVInputFormat *in_fmt = NULL;
+int highest_cur_seq_no = 0;
+int ret;
+int i;
+
+if (!(pls->ctx = avformat_alloc_context())) {
+return AVERROR(ENOMEM);
+}
+
+if (pls->n_segments == 0)
+return 0;
+
+pls->needed = 1;
+pls->parent = c->ctx;
+
+/*
+ * If this is a live stream and this playlist looks like it is one segment
+ * behind, try to sync it up so that every substream starts at the same
+ * time position (so e.g. avformat_find_stream_info() will see packets from
+ * all active streams within the first few seconds). This is not very 
generic,
+ * though, as the sequence numbers are technically independent.
+ */
+highest_cur_seq_no = 0;
+for (i = 0; i < c->n_playlists; i++) {
+struct playlist *pls = c->playlists[i];
+if (pls->cur_seq_no > highest_cur_seq_no)
+highest_cur_seq_no = pls->cur_seq_no;
+}
+if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
+highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
+pls->cur_seq_no = highest_cur_seq_no;
+}
+
+pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
+if (!pls->read_buffer){
+ret = AVERROR(ENOMEM);
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+ffio_init_context(>pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
+  read_data, NULL, NULL);
+pls->pb.seekable = 0;
+ret = av_probe_input_buffer(>pb, _fmt, pls->segments[0]->url,
+NULL, 0, 0);
+if (ret < 0) {
+/* Free the ctx - it isn't initialized properly at this point,
+ * so avformat_close_input shouldn't be called. If
+ * avformat_open_input fails below, it frees and zeros the
+ * context, so it doesn't need any special treatment like this. */
+av_log(c->ctx, AV_LOG_ERROR, "Error when loading first segment 
'%s'\n", pls->segments[0]->url);
+avio_closep(>pb);
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+pls->ctx->pb   = >pb;
+pls->ctx->io_open  = nested_io_open;
+pls->ctx->flags   |= c->ctx->flags & ~AVFMT_FLAG_CUSTOM_IO;
+
+if ((ret = ff_copy_whiteblacklists(pls->ctx, c->ctx)) < 0)
+return ret;
+
+ret = avformat_open_input(>ctx, pls->segments[0]->url, in_fmt, NULL);
+if (ret < 0) {
+av_log(c->ctx, AV_LOG_ERROR, "Error opening playlist %s", 
pls->segments[0]->url);
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+
+if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
+ff_id3v2_parse_apic(pls->ctx, >id3_deferred_extra);
+avformat_queue_attached_pictures(pls->ctx);
+ff_id3v2_free_extra_meta(>id3_deferred_extra);
+pls->id3_deferred_extra = NULL;
+}
+
+if (pls->is_id3_timestamped == -1)
+av_log(c->ctx, AV_LOG_WARNING, "No expected HTTP requests have been 
made\n");
+
+/*
+ * For ID3 timestamped raw audio streams we need to detect the packet
+ * durations to calculate timestamps in 
fill_timing_for_id3_timestamped_stream(),
+ * but for other streams we can rely on our user calling 
avformat_find_stream_info()
+ * on us if they want to.
+ */
+if (pls->is_id3_timestamped) {
+ret = avformat_find_stream_info(pls->ctx, NULL);
+if (ret < 0) {
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+}
+
+pls->has_noheader_flag = !!(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER);
+
+/* Create new AVStreams for each stream in this playlist */
+ret = update_streams_from_subdemuxer(c->ctx, pls);
+if (ret < 0) {
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+
+add_metadata_from_renditions(c->ctx, pls, AVMEDIA_TYPE_AUDIO);
+add_metadata_from_renditions(c->ctx, pls, AVMEDIA_TYPE_VIDEO);
+add_metadata_from_renditions(c->ctx, pls, AVMEDIA_TYPE_SUBTITLE);
+
+return 0;
+}
+
 static int hls_read_header(AVFormatContext *s)
 {
 void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb;
@@ -1775,97 

[FFmpeg-devel] [PATCH v4 2/2] lavf/hls: add option to defer parsing of variants

2017-12-03 Thread Rainer Hochecker
---
 doc/demuxers.texi |   6 
 libavformat/hls.c | 106 ++
 2 files changed, 98 insertions(+), 14 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 73dc0feec1..33643f966a 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -316,6 +316,12 @@ segment index to start live streams at (negative values 
are from the end).
 @item max_reload
 Maximum number of times a insufficient list is attempted to be reloaded.
 Default value is 1000.
+
+@item load_all_variants
+If 0, only the first variant/playlist is loaded on open. All other variants
+get disabled and can be enabled by setting discard option in program.
+Default value is 1.
+
 @end table
 
 @section image2
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 3c2c720abe..500e3c15de 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -112,6 +112,7 @@ struct playlist {
 int n_segments;
 struct segment **segments;
 int needed;
+int parsed;
 int cur_seq_no;
 int64_t cur_seg_offset;
 int64_t last_load_time;
@@ -206,6 +207,7 @@ typedef struct HLSContext {
 int strict_std_compliance;
 char *allowed_extensions;
 int max_reload;
+int load_all_variants;
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -315,6 +317,7 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
 pls->index = c->n_playlists;
+pls->parsed = 0;
 pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
@@ -867,6 +870,10 @@ fail:
 av_free(new_url);
 if (close_in)
 ff_format_io_close(c->ctx, );
+
+if (pls)
+pls->parsed = 1;
+
 return ret;
 }
 
@@ -1260,17 +1267,30 @@ static int64_t default_reload_interval(struct playlist 
*pls)
   pls->target_duration;
 }
 
-static int playlist_needed(struct playlist *pls)
+static int playlist_needed(AVFormatContext *s, struct playlist *pls, int 
check_parsed)
 {
-AVFormatContext *s = pls->parent;
+HLSContext *c = s->priv_data;
 int i, j;
 int stream_needed = 0;
 int first_st;
 
 /* If there is no context or streams yet, the playlist is needed */
-if (!pls->ctx || !pls->n_main_streams)
+if (check_parsed && (!pls->ctx || !pls->n_main_streams))
 return 1;
 
+/* If the playlist belongs to a non discarded variant and is not parsed,
+ * we need to parse and activate it later */
+for (i = 0; i < s->nb_programs; i++) {
+AVProgram *program = s->programs[i];
+struct variant *var = c->variants[i];
+if (program->discard < AVDISCARD_ALL) {
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == pls && !var->playlists[j]->parsed)
+return  1;
+}
+}
+}
+
 /* check if any of the streams in the playlist are needed */
 for (i = 0; i < pls->n_main_streams; i++) {
 if (pls->main_streams[i]->discard < AVDISCARD_ALL) {
@@ -1324,7 +1344,7 @@ restart:
 
 /* Check that the playlist is still needed before opening a new
  * segment. */
-v->needed = playlist_needed(v);
+v->needed = playlist_needed(v->parent, v, 1);
 
 if (!v->needed) {
 av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d\n",
@@ -1418,23 +1438,41 @@ reload:
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
   enum AVMediaType type, const char 
*group_id)
 {
-int i;
+int i, j;
+int found;
 
 for (i = 0; i < c->n_renditions; i++) {
 struct rendition *rend = c->renditions[i];
 
 if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 
-if (rend->playlist)
+if (rend->playlist) {
 /* rendition is an external playlist
  * => add the playlist to the variant */
-dynarray_add(>playlists, >n_playlists, 
rend->playlist);
-else
+found = 0;
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == rend->playlist) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists, >n_playlists, 
rend->playlist);
+} else {
 /* rendition is part of the variant main Media Playlist
  * => add the rendition to the main Media Playlist */
-dynarray_add(>playlists[0]->renditions,
- >playlists[0]->n_renditions,
- rend);
+found = 0;
+for (j = 0; j < var->playlists[0]->n_renditions; j++) {
+if (var->playlists[0]->renditions[j] == rend) {
+

[FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-12-03 Thread Rainer Hochecker
v4: fixed the memleak properly
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH v3 2/2] lavf/hls: add option to defer parsing of variants

2017-12-03 Thread Rainer Hochecker
---
 doc/demuxers.texi |   6 
 libavformat/hls.c | 106 ++
 2 files changed, 98 insertions(+), 14 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 73dc0feec1..33643f966a 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -316,6 +316,12 @@ segment index to start live streams at (negative values 
are from the end).
 @item max_reload
 Maximum number of times a insufficient list is attempted to be reloaded.
 Default value is 1000.
+
+@item load_all_variants
+If 0, only the first variant/playlist is loaded on open. All other variants
+get disabled and can be enabled by setting discard option in program.
+Default value is 1.
+
 @end table
 
 @section image2
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 3f83707c1f..731e8a569c 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -112,6 +112,7 @@ struct playlist {
 int n_segments;
 struct segment **segments;
 int needed;
+int parsed;
 int cur_seq_no;
 int64_t cur_seg_offset;
 int64_t last_load_time;
@@ -206,6 +207,7 @@ typedef struct HLSContext {
 int strict_std_compliance;
 char *allowed_extensions;
 int max_reload;
+int load_all_variants;
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -315,6 +317,7 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
 pls->index = c->n_playlists;
+pls->parsed = 0;
 pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
@@ -867,6 +870,10 @@ fail:
 av_free(new_url);
 if (close_in)
 ff_format_io_close(c->ctx, );
+
+if (pls)
+pls->parsed = 1;
+
 return ret;
 }
 
@@ -1260,17 +1267,30 @@ static int64_t default_reload_interval(struct playlist 
*pls)
   pls->target_duration;
 }
 
-static int playlist_needed(struct playlist *pls)
+static int playlist_needed(AVFormatContext *s, struct playlist *pls, int 
check_parsed)
 {
-AVFormatContext *s = pls->parent;
+HLSContext *c = s->priv_data;
 int i, j;
 int stream_needed = 0;
 int first_st;
 
 /* If there is no context or streams yet, the playlist is needed */
-if (!pls->ctx || !pls->n_main_streams)
+if (check_parsed && (!pls->ctx || !pls->n_main_streams))
 return 1;
 
+/* If the playlist belongs to a non discarded variant and is not parsed,
+ * we need to parse and activate it later */
+for (i = 0; i < s->nb_programs; i++) {
+AVProgram *program = s->programs[i];
+struct variant *var = c->variants[i];
+if (program->discard < AVDISCARD_ALL) {
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == pls && !var->playlists[j]->parsed)
+return  1;
+}
+}
+}
+
 /* check if any of the streams in the playlist are needed */
 for (i = 0; i < pls->n_main_streams; i++) {
 if (pls->main_streams[i]->discard < AVDISCARD_ALL) {
@@ -1324,7 +1344,7 @@ restart:
 
 /* Check that the playlist is still needed before opening a new
  * segment. */
-v->needed = playlist_needed(v);
+v->needed = playlist_needed(v->parent, v, 1);
 
 if (!v->needed) {
 av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d\n",
@@ -1418,23 +1438,41 @@ reload:
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
   enum AVMediaType type, const char 
*group_id)
 {
-int i;
+int i, j;
+int found;
 
 for (i = 0; i < c->n_renditions; i++) {
 struct rendition *rend = c->renditions[i];
 
 if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 
-if (rend->playlist)
+if (rend->playlist) {
 /* rendition is an external playlist
  * => add the playlist to the variant */
-dynarray_add(>playlists, >n_playlists, 
rend->playlist);
-else
+found = 0;
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == rend->playlist) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists, >n_playlists, 
rend->playlist);
+} else {
 /* rendition is part of the variant main Media Playlist
  * => add the rendition to the main Media Playlist */
-dynarray_add(>playlists[0]->renditions,
- >playlists[0]->n_renditions,
- rend);
+found = 0;
+for (j = 0; j < var->playlists[0]->n_renditions; j++) {
+if (var->playlists[0]->renditions[j] == rend) {
+

[FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-12-03 Thread Rainer Hochecker
fixed mem leak poined out by Steven
 
---
 doc/demuxers.texi |   5 +
 libavformat/hls.c | 304 --
 2 files changed, 209 insertions(+), 100 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 73dc0feec1..634b122e10 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -316,6 +316,11 @@ segment index to start live streams at (negative values 
are from the end).
 @item max_reload
 Maximum number of times a insufficient list is attempted to be reloaded.
 Default value is 1000.
+
+@item load_all_variants
+If 0, only the first variant/playlist is loaded on open. All other variants
+get disabled and can be enabled by setting discard option in program.
+Default value is 1.
 @end table
 
 @section image2
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 786934af03..c42e0b0f95 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -112,6 +112,7 @@ struct playlist {
 int n_segments;
 struct segment **segments;
 int needed, cur_needed;
+int parsed;
 int cur_seq_no;
 int64_t cur_seg_offset;
 int64_t last_load_time;
@@ -206,6 +207,7 @@ typedef struct HLSContext {
 int strict_std_compliance;
 char *allowed_extensions;
 int max_reload;
+int load_all_variants;
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -314,6 +316,9 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->is_id3_timestamped = -1;
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
+pls->index = c->n_playlists;
+pls->parsed = 0;
+pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
 }
@@ -721,6 +726,7 @@ static int parse_playlist(HLSContext *c, const char *url,
 free_segment_list(pls);
 pls->finished = 0;
 pls->type = PLS_TYPE_UNSPECIFIED;
+pls->parsed = 1;
 }
 while (!avio_feof(in)) {
 read_chomp_line(in, line, sizeof(line));
@@ -1377,23 +1383,41 @@ reload:
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
   enum AVMediaType type, const char 
*group_id)
 {
-int i;
+int i, j;
+int found;
 
 for (i = 0; i < c->n_renditions; i++) {
 struct rendition *rend = c->renditions[i];
 
 if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 
-if (rend->playlist)
+if (rend->playlist) {
 /* rendition is an external playlist
  * => add the playlist to the variant */
-dynarray_add(>playlists, >n_playlists, 
rend->playlist);
-else
+found = 0;
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == rend->playlist) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists, >n_playlists, 
rend->playlist);
+} else {
 /* rendition is part of the variant main Media Playlist
  * => add the rendition to the main Media Playlist */
-dynarray_add(>playlists[0]->renditions,
- >playlists[0]->n_renditions,
- rend);
+found = 0;
+for (j = 0; j < var->playlists[0]->n_renditions; j++) {
+if (var->playlists[0]->renditions[j] == rend) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists[0]->renditions,
+ >playlists[0]->n_renditions,
+ rend);
+}
 }
 }
 }
@@ -1631,6 +1655,124 @@ static int hls_close(AVFormatContext *s)
 return 0;
 }
 
+static int init_playlist(HLSContext *c, struct playlist *pls)
+{
+AVInputFormat *in_fmt = NULL;
+int highest_cur_seq_no = 0;
+int ret;
+int i;
+
+if (!(pls->ctx = avformat_alloc_context())) {
+return AVERROR(ENOMEM);
+}
+
+if (pls->n_segments == 0)
+return 0;
+
+pls->needed = 1;
+pls->parent = c->ctx;
+
+/*
+ * If this is a live stream and this playlist looks like it is one segment
+ * behind, try to sync it up so that every substream starts at the same
+ * time position (so e.g. avformat_find_stream_info() will see packets from
+ * all active streams within the first few seconds). This is not very 
generic,
+ * though, as the sequence numbers are technically independent.
+ */
+highest_cur_seq_no = 0;
+for (i = 0; i < c->n_playlists; i++) {
+struct playlist *pls = c->playlists[i];
+if (!pls->parsed)
+continue;
+if (pls->cur_seq_no > highest_cur_seq_no)
+highest_cur_seq_no = 

[FFmpeg-devel] [PATCH v3 1/2] lavf/hls: refactoring of read_header

2017-12-03 Thread Rainer Hochecker
---
 libavformat/hls.c | 209 +++---
 1 file changed, 120 insertions(+), 89 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index ab6ff187a6..3f83707c1f 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -314,6 +314,8 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->is_id3_timestamped = -1;
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
+pls->index = c->n_playlists;
+pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
 }
@@ -1670,6 +1672,122 @@ static int hls_close(AVFormatContext *s)
 return 0;
 }
 
+static int init_playlist(HLSContext *c, struct playlist *pls)
+{
+AVInputFormat *in_fmt = NULL;
+int highest_cur_seq_no = 0;
+int ret;
+int i;
+
+if (!(pls->ctx = avformat_alloc_context())) {
+return AVERROR(ENOMEM);
+}
+
+if (pls->n_segments == 0)
+return 0;
+
+pls->needed = 1;
+pls->parent = c->ctx;
+
+/*
+ * If this is a live stream and this playlist looks like it is one segment
+ * behind, try to sync it up so that every substream starts at the same
+ * time position (so e.g. avformat_find_stream_info() will see packets from
+ * all active streams within the first few seconds). This is not very 
generic,
+ * though, as the sequence numbers are technically independent.
+ */
+highest_cur_seq_no = 0;
+for (i = 0; i < c->n_playlists; i++) {
+struct playlist *pls = c->playlists[i];
+if (pls->cur_seq_no > highest_cur_seq_no)
+highest_cur_seq_no = pls->cur_seq_no;
+}
+if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
+highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
+pls->cur_seq_no = highest_cur_seq_no;
+}
+
+pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
+if (!pls->read_buffer){
+ret = AVERROR(ENOMEM);
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+ffio_init_context(>pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
+  read_data, NULL, NULL);
+pls->pb.seekable = 0;
+ret = av_probe_input_buffer(>pb, _fmt, pls->segments[0]->url,
+NULL, 0, 0);
+if (ret < 0) {
+/* Free the ctx - it isn't initialized properly at this point,
+ * so avformat_close_input shouldn't be called. If
+ * avformat_open_input fails below, it frees and zeros the
+ * context, so it doesn't need any special treatment like this. */
+av_log(c->ctx, AV_LOG_ERROR, "Error when loading first segment 
'%s'\n", pls->segments[0]->url);
+av_free(pls->read_buffer);
+pls->read_buffer = NULL;
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+pls->ctx->pb   = >pb;
+pls->ctx->io_open  = nested_io_open;
+pls->ctx->flags   |= c->ctx->flags & ~AVFMT_FLAG_CUSTOM_IO;
+
+if ((ret = ff_copy_whiteblacklists(pls->ctx, c->ctx)) < 0)
+return ret;
+
+ret = avformat_open_input(>ctx, pls->segments[0]->url, in_fmt, NULL);
+if (ret < 0) {
+av_log(c->ctx, AV_LOG_ERROR, "Error opening playlist %s", 
pls->segments[0]->url);
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+
+if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
+ff_id3v2_parse_apic(pls->ctx, >id3_deferred_extra);
+avformat_queue_attached_pictures(pls->ctx);
+ff_id3v2_free_extra_meta(>id3_deferred_extra);
+pls->id3_deferred_extra = NULL;
+}
+
+if (pls->is_id3_timestamped == -1)
+av_log(c->ctx, AV_LOG_WARNING, "No expected HTTP requests have been 
made\n");
+
+/*
+ * For ID3 timestamped raw audio streams we need to detect the packet
+ * durations to calculate timestamps in 
fill_timing_for_id3_timestamped_stream(),
+ * but for other streams we can rely on our user calling 
avformat_find_stream_info()
+ * on us if they want to.
+ */
+if (pls->is_id3_timestamped) {
+ret = avformat_find_stream_info(pls->ctx, NULL);
+if (ret < 0) {
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+}
+
+pls->has_noheader_flag = !!(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER);
+
+/* Create new AVStreams for each stream in this playlist */
+ret = update_streams_from_subdemuxer(c->ctx, pls);
+if (ret < 0) {
+avformat_free_context(pls->ctx);
+pls->ctx = NULL;
+return ret;
+}
+
+add_metadata_from_renditions(c->ctx, pls, AVMEDIA_TYPE_AUDIO);
+add_metadata_from_renditions(c->ctx, pls, AVMEDIA_TYPE_VIDEO);
+add_metadata_from_renditions(c->ctx, pls, AVMEDIA_TYPE_SUBTITLE);
+
+return 0;
+}
+
 static int hls_read_header(AVFormatContext *s)
 {
 void *u = (s->flags & 

[FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-12-03 Thread Rainer Hochecker
I tried to implement what you requested
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-27 Thread Rainer Hochecker
2017-11-27 22:53 GMT+01:00 Anssi Hannula <anssi.hann...@iki.fi>:
> Hi,
>
> Rainer Hochecker kirjoitti 2017-11-26 12:46:
>>
>> fixed mem leak poined out by Steven
>>
>> ---
>>  doc/demuxers.texi |   5 +
>>  libavformat/hls.c | 304
>> --
>>  2 files changed, 209 insertions(+), 100 deletions(-)
>>
> [...]
>>
>> +
>> +@item load_all_variants
>> +If 0, only the first variant/playlist is loaded on open. All other
>> variants
>> +get disabled and can be enabled by setting discard option in program.
>> +Default value is 1.
>>  @end table
>
>
> If playlist download+parsing is indeed taking long enough time that this is
> warranted, I wonder if we should maybe just never read any variant playlists
> in read_header(), and instead set AVFMTCTX_NOHEADER.
> Then the user may discard AVPrograms right after open, before unneeded
> playlists are loaded+parsed.
>
> This would avoid having a separate option/mode for this.
>
> Any thoughts?

I actually tried it like this but somwhow did not like it because this
is different
to all other demuxers/formats. In general you open an input, call
find_stream_info,
and select a program. I did not like selecting the program between open and
find_stream_info.

>
>
>>  @section image2
>> diff --git a/libavformat/hls.c b/libavformat/hls.c
>> index 786934af03..c42e0b0f95 100644
>> --- a/libavformat/hls.c
>> +++ b/libavformat/hls.c
>> @@ -112,6 +112,7 @@ struct playlist {
>>  int n_segments;
>>  struct segment **segments;
>>  int needed, cur_needed;
>> +int parsed;
>>  int cur_seq_no;
>>  int64_t cur_seg_offset;
>>  int64_t last_load_time;
>> @@ -206,6 +207,7 @@ typedef struct HLSContext {
>>  int strict_std_compliance;
>>  char *allowed_extensions;
>>  int max_reload;
>> +int load_all_variants;
>>  } HLSContext;
>
> [...]
>>
>> @@ -721,6 +726,7 @@ static int parse_playlist(HLSContext *c, const char
>> *url,
>>  free_segment_list(pls);
>>  pls->finished = 0;
>>  pls->type = PLS_TYPE_UNSPECIFIED;
>> +pls->parsed = 1;
>>  }
>
>
> That "pls->parsed = 1" is in the "reinit old playlist for re-parse" block,
> is that intentional?
>
> I'd think it should rather be at the end of the function alongside setting
> pls->last_load_time, so it is set to 1 whenever parsing has been done.
>

I put it at the beginning because I wanted to avoid that it gets tried again
on error.

>>  while (!avio_feof(in)) {
>>  read_chomp_line(in, line, sizeof(line));
>
> [...]
>>
>> @@ -1631,6 +1655,124 @@ static int hls_close(AVFormatContext *s)
>>  return 0;
>>  }
>>
>> +static int init_playlist(HLSContext *c, struct playlist *pls)
>> +{
>
>
> This init_playlist() seems to be mostly code moved from below, could you
> split the patch so that the first patch moves the code around but does not
> change behavior, and the second patch makes the actual changes (i.e. adds
> the option)?
>
> That would ease e.g. future bisecting.

Sure. At least I can try.

>
> [...]
>>
>> +return 0;
>> +}
>> +
>>  static int hls_read_header(AVFormatContext *s)
>>  {
>>  void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb;
>> @@ -1663,6 +1805,9 @@ static int hls_read_header(AVFormatContext *s)
>>  if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
>>  goto fail;
>>
>> +/* first playlist was created, set it to parsed */
>> +c->variants[0]->playlists[0]->parsed = 1;
>> +
>
>
> I think parse_playlist() should set this when it parses something.

That was pitfall for my v1. The first playlist gets parsed with no
playlist given as argument.
fate failed because non-master playlists were not set to parsed.

>
>>  if ((ret = save_avio_options(s)) < 0)
>>  goto fail;
>>
>> @@ -1675,8 +1820,15 @@ static int hls_read_header(AVFormatContext *s)
>>  goto fail;
>
> [...]
>>
>>
>>  /* Select the starting segments */
>>  for (i = 0; i < c->n_playlists; i++) {
>>  struct playlist *pls = c->playlists[i];
>>
>> -if (pls->n_segments == 0)
>> +if (pls->n_segments == 0 && !pls->parsed)
>>  continue;
>
>
> Why?

playlists not parsed are invalid, right? maybe n_segments is 0 for
not parsed playlists but this was no obvious to me.

>
>>  pls->cur_seq_no = select_cur_seq_no(c, pls);
>> @@ -1736,97 +1892,9 @@ static int hls_read_header(AVFormatContext *s)
>>  /* Open the demuxer for each playlist */
>>  for (i = 0; i < c->n_playlists; i++) {
>>  struct playlist *pls = c->playlists[i];
>> -AVInputFormat *in_fmt = NULL;
>> -
>
> [...]
>
> --
> Anssi Hannula
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-26 Thread Rainer Hochecker

Variants are presented as programs and can be loaded later by
setting discard flags on the program. Currently Kodi chooses the
program that best matches the desired bit rate.

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


Re: [FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-26 Thread Rainer Hochecker
2017-11-26 12:04 GMT+01:00 Steven Liu <lingjiujia...@gmail.com>:
> 2017-11-26 18:46 GMT+08:00 Rainer Hochecker <fernetme...@online.de>:
>> fixed mem leak poined out by Steven
> Hi Rainer,
>
> I'm not sure that is memleak, but looks like memleak when reading
> the code, i see the code always in hls.c before this patch, but no
> people report it memleak.
> If that is memleak, maybe use goto method is better way, because
> the workflow of bellow have alloc resource faild check, i will point
> out base on your patch.
>>

Hi Steven,

As soon as you associate the probe buffer with the context, the context cares
about allocated resources. That's most likely the reason why pb was not
cleared here. It is assigned to the context right after this block.

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


Re: [FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-26 Thread Rainer Hochecker
>> +/*
>> + * If this is a live stream and this playlist looks like it is one 
>> segment
>> + * behind, try to sync it up so that every substream starts at the same
>> + * time position (so e.g. avformat_find_stream_info() will see packets 
>> from
>> + * all active streams within the first few seconds). This is not very 
>> generic,
>> + * though, as the sequence numbers are technically independent.
>> + */
>> +highest_cur_seq_no = 0;
>> +for (i = 0; i < c->n_playlists; i++) {
>> +struct playlist *pls = c->playlists[i];
>> +if (!pls->parsed)
>> +continue;
>> +if (pls->cur_seq_no > highest_cur_seq_no)
>> +highest_cur_seq_no = pls->cur_seq_no;
>> +}
>> +if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
>> +highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
>> +pls->cur_seq_no = highest_cur_seq_no;
>> +}
>> +
>> +pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
>> +if (!pls->read_buffer){
>> +ret = AVERROR(ENOMEM);
>> +avformat_free_context(pls->ctx);
>> +pls->ctx = NULL;
>> +return ret;
>> +}
>> +ffio_init_context(>pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, 
>> pls,
>> +  read_data, NULL, NULL);
>> +pls->pb.seekable = 0;
>> +ret = av_probe_input_buffer(>pb, _fmt, pls->segments[0]->url,
>> +NULL, 0, 0);
>> +if (ret < 0) {
>> +/* Free the ctx - it isn't initialized properly at this point,
>> + * so avformat_close_input shouldn't be called. If
>> + * avformat_open_input fails below, it frees and zeros the
>> + * context, so it doesn't need any special treatment like this. */
>> +av_log(c->ctx, AV_LOG_ERROR, "Error when loading first segment 
>> '%s'\n", pls->segments[0]->url);
>> +avformat_free_context(pls->ctx);
>> +pls->ctx = NULL;
>> +return ret;
> Is that pls->read_buffer will memleak?
>
>

yes, looks like this. this is already an issue in current code.
nevertheless, I will fix it here.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-26 Thread Rainer Hochecker
fixed mem leak poined out by Steven
 
---
 doc/demuxers.texi |   5 +
 libavformat/hls.c | 304 --
 2 files changed, 209 insertions(+), 100 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 73dc0feec1..634b122e10 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -316,6 +316,11 @@ segment index to start live streams at (negative values 
are from the end).
 @item max_reload
 Maximum number of times a insufficient list is attempted to be reloaded.
 Default value is 1000.
+
+@item load_all_variants
+If 0, only the first variant/playlist is loaded on open. All other variants
+get disabled and can be enabled by setting discard option in program.
+Default value is 1.
 @end table
 
 @section image2
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 786934af03..c42e0b0f95 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -112,6 +112,7 @@ struct playlist {
 int n_segments;
 struct segment **segments;
 int needed, cur_needed;
+int parsed;
 int cur_seq_no;
 int64_t cur_seg_offset;
 int64_t last_load_time;
@@ -206,6 +207,7 @@ typedef struct HLSContext {
 int strict_std_compliance;
 char *allowed_extensions;
 int max_reload;
+int load_all_variants;
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -314,6 +316,9 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->is_id3_timestamped = -1;
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
+pls->index = c->n_playlists;
+pls->parsed = 0;
+pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
 }
@@ -721,6 +726,7 @@ static int parse_playlist(HLSContext *c, const char *url,
 free_segment_list(pls);
 pls->finished = 0;
 pls->type = PLS_TYPE_UNSPECIFIED;
+pls->parsed = 1;
 }
 while (!avio_feof(in)) {
 read_chomp_line(in, line, sizeof(line));
@@ -1377,23 +1383,41 @@ reload:
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
   enum AVMediaType type, const char 
*group_id)
 {
-int i;
+int i, j;
+int found;
 
 for (i = 0; i < c->n_renditions; i++) {
 struct rendition *rend = c->renditions[i];
 
 if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 
-if (rend->playlist)
+if (rend->playlist) {
 /* rendition is an external playlist
  * => add the playlist to the variant */
-dynarray_add(>playlists, >n_playlists, 
rend->playlist);
-else
+found = 0;
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == rend->playlist) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists, >n_playlists, 
rend->playlist);
+} else {
 /* rendition is part of the variant main Media Playlist
  * => add the rendition to the main Media Playlist */
-dynarray_add(>playlists[0]->renditions,
- >playlists[0]->n_renditions,
- rend);
+found = 0;
+for (j = 0; j < var->playlists[0]->n_renditions; j++) {
+if (var->playlists[0]->renditions[j] == rend) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists[0]->renditions,
+ >playlists[0]->n_renditions,
+ rend);
+}
 }
 }
 }
@@ -1631,6 +1655,124 @@ static int hls_close(AVFormatContext *s)
 return 0;
 }
 
+static int init_playlist(HLSContext *c, struct playlist *pls)
+{
+AVInputFormat *in_fmt = NULL;
+int highest_cur_seq_no = 0;
+int ret;
+int i;
+
+if (!(pls->ctx = avformat_alloc_context())) {
+return AVERROR(ENOMEM);
+}
+
+if (pls->n_segments == 0)
+return 0;
+
+pls->needed = 1;
+pls->parent = c->ctx;
+
+/*
+ * If this is a live stream and this playlist looks like it is one segment
+ * behind, try to sync it up so that every substream starts at the same
+ * time position (so e.g. avformat_find_stream_info() will see packets from
+ * all active streams within the first few seconds). This is not very 
generic,
+ * though, as the sequence numbers are technically independent.
+ */
+highest_cur_seq_no = 0;
+for (i = 0; i < c->n_playlists; i++) {
+struct playlist *pls = c->playlists[i];
+if (!pls->parsed)
+continue;
+if (pls->cur_seq_no > highest_cur_seq_no)
+highest_cur_seq_no = 

[FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-25 Thread Rainer Hochecker
fate runs now without error, sorry for that

---
 doc/demuxers.texi |   5 +
 libavformat/hls.c | 302 --
 2 files changed, 207 insertions(+), 100 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 73dc0feec1..634b122e10 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -316,6 +316,11 @@ segment index to start live streams at (negative values 
are from the end).
 @item max_reload
 Maximum number of times a insufficient list is attempted to be reloaded.
 Default value is 1000.
+
+@item load_all_variants
+If 0, only the first variant/playlist is loaded on open. All other variants
+get disabled and can be enabled by setting discard option in program.
+Default value is 1.
 @end table
 
 @section image2
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 786934af03..c1c93f8067 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -112,6 +112,7 @@ struct playlist {
 int n_segments;
 struct segment **segments;
 int needed, cur_needed;
+int parsed;
 int cur_seq_no;
 int64_t cur_seg_offset;
 int64_t last_load_time;
@@ -206,6 +207,7 @@ typedef struct HLSContext {
 int strict_std_compliance;
 char *allowed_extensions;
 int max_reload;
+int load_all_variants;
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -314,6 +316,9 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->is_id3_timestamped = -1;
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
+pls->index = c->n_playlists;
+pls->parsed = 0;
+pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
 }
@@ -721,6 +726,7 @@ static int parse_playlist(HLSContext *c, const char *url,
 free_segment_list(pls);
 pls->finished = 0;
 pls->type = PLS_TYPE_UNSPECIFIED;
+pls->parsed = 1;
 }
 while (!avio_feof(in)) {
 read_chomp_line(in, line, sizeof(line));
@@ -1377,23 +1383,41 @@ reload:
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
   enum AVMediaType type, const char 
*group_id)
 {
-int i;
+int i, j;
+int found;
 
 for (i = 0; i < c->n_renditions; i++) {
 struct rendition *rend = c->renditions[i];
 
 if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 
-if (rend->playlist)
+if (rend->playlist) {
 /* rendition is an external playlist
  * => add the playlist to the variant */
-dynarray_add(>playlists, >n_playlists, 
rend->playlist);
-else
+found = 0;
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == rend->playlist) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists, >n_playlists, 
rend->playlist);
+} else {
 /* rendition is part of the variant main Media Playlist
  * => add the rendition to the main Media Playlist */
-dynarray_add(>playlists[0]->renditions,
- >playlists[0]->n_renditions,
- rend);
+found = 0;
+for (j = 0; j < var->playlists[0]->n_renditions; j++) {
+if (var->playlists[0]->renditions[j] == rend) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists[0]->renditions,
+ >playlists[0]->n_renditions,
+ rend);
+}
 }
 }
 }
@@ -1631,6 +1655,122 @@ static int hls_close(AVFormatContext *s)
 return 0;
 }
 
+static int init_playlist(HLSContext *c, struct playlist *pls)
+{
+AVInputFormat *in_fmt = NULL;
+int highest_cur_seq_no = 0;
+int ret;
+int i;
+
+if (!(pls->ctx = avformat_alloc_context())) {
+return AVERROR(ENOMEM);
+}
+
+if (pls->n_segments == 0)
+return 0;
+
+pls->needed = 1;
+pls->parent = c->ctx;
+
+/*
+ * If this is a live stream and this playlist looks like it is one segment
+ * behind, try to sync it up so that every substream starts at the same
+ * time position (so e.g. avformat_find_stream_info() will see packets from
+ * all active streams within the first few seconds). This is not very 
generic,
+ * though, as the sequence numbers are technically independent.
+ */
+highest_cur_seq_no = 0;
+for (i = 0; i < c->n_playlists; i++) {
+struct playlist *pls = c->playlists[i];
+if (!pls->parsed)
+continue;
+if (pls->cur_seq_no > highest_cur_seq_no)
+highest_cur_seq_no = 

Re: [FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-24 Thread Rainer Hochecker

Shouldn't this be:
0 (or -1) for all streams (default), n>0 (or > -1) for the nth stream.
I guess it is at least possible that the user knows in advance which
streams the source will offer.
No?

Carl Eugen


It is very unlikely that this is known in advance. Also there is no reason
why you want to load more than a single variant at a time.
Note this are variants, not streams. Different variants bundle the same
streams with different resolutions.

Rainer

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


[FFmpeg-devel] (no subject)

2017-11-23 Thread Rainer Hochecker

Currently all variants/playlists get parsed on open. For a master playlist
with many different bitrates this can take several seconds. With the new
option set to 0 only the first variant of a master playlist is opened. Others
can be activated later by setting discard option on a program. Default value
of option preserves current behaviour.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] hls demuxer: add option to defer parsing of variants

2017-11-23 Thread Rainer Hochecker
---
 doc/demuxers.texi |   5 +
 libavformat/hls.c | 299 --
 2 files changed, 204 insertions(+), 100 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 73dc0feec1..634b122e10 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -316,6 +316,11 @@ segment index to start live streams at (negative values 
are from the end).
 @item max_reload
 Maximum number of times a insufficient list is attempted to be reloaded.
 Default value is 1000.
+
+@item load_all_variants
+If 0, only the first variant/playlist is loaded on open. All other variants
+get disabled and can be enabled by setting discard option in program.
+Default value is 1.
 @end table
 
 @section image2
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 786934af03..c55f5ea439 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -112,6 +112,7 @@ struct playlist {
 int n_segments;
 struct segment **segments;
 int needed, cur_needed;
+int parsed;
 int cur_seq_no;
 int64_t cur_seg_offset;
 int64_t last_load_time;
@@ -206,6 +207,7 @@ typedef struct HLSContext {
 int strict_std_compliance;
 char *allowed_extensions;
 int max_reload;
+int load_all_variants;
 } HLSContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -314,6 +316,9 @@ static struct playlist *new_playlist(HLSContext *c, const 
char *url,
 pls->is_id3_timestamped = -1;
 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
 
+pls->index = c->n_playlists;
+pls->parsed = 0;
+pls->needed = 0;
 dynarray_add(>playlists, >n_playlists, pls);
 return pls;
 }
@@ -721,6 +726,7 @@ static int parse_playlist(HLSContext *c, const char *url,
 free_segment_list(pls);
 pls->finished = 0;
 pls->type = PLS_TYPE_UNSPECIFIED;
+pls->parsed = 1;
 }
 while (!avio_feof(in)) {
 read_chomp_line(in, line, sizeof(line));
@@ -1377,23 +1383,41 @@ reload:
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
   enum AVMediaType type, const char 
*group_id)
 {
-int i;
+int i, j;
+int found;
 
 for (i = 0; i < c->n_renditions; i++) {
 struct rendition *rend = c->renditions[i];
 
 if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 
-if (rend->playlist)
+if (rend->playlist) {
 /* rendition is an external playlist
  * => add the playlist to the variant */
-dynarray_add(>playlists, >n_playlists, 
rend->playlist);
-else
+found = 0;
+for (j = 0; j < var->n_playlists; j++) {
+if (var->playlists[j] == rend->playlist) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists, >n_playlists, 
rend->playlist);
+} else {
 /* rendition is part of the variant main Media Playlist
  * => add the rendition to the main Media Playlist */
-dynarray_add(>playlists[0]->renditions,
- >playlists[0]->n_renditions,
- rend);
+found = 0;
+for (j = 0; j < var->playlists[0]->n_renditions; j++) {
+if (var->playlists[0]->renditions[j] == rend) {
+found = 1;
+break;
+}
+}
+if (!found)
+dynarray_add(>playlists[0]->renditions,
+ >playlists[0]->n_renditions,
+ rend);
+}
 }
 }
 }
@@ -1631,6 +1655,122 @@ static int hls_close(AVFormatContext *s)
 return 0;
 }
 
+static int init_playlist(HLSContext *c, struct playlist *pls)
+{
+AVInputFormat *in_fmt = NULL;
+int highest_cur_seq_no = 0;
+int ret;
+int i;
+
+if (!(pls->ctx = avformat_alloc_context())) {
+return AVERROR(ENOMEM);
+}
+
+if (pls->n_segments == 0)
+return 0;
+
+pls->needed = 1;
+pls->parent = c->ctx;
+
+/*
+ * If this is a live stream and this playlist looks like it is one segment
+ * behind, try to sync it up so that every substream starts at the same
+ * time position (so e.g. avformat_find_stream_info() will see packets from
+ * all active streams within the first few seconds). This is not very 
generic,
+ * though, as the sequence numbers are technically independent.
+ */
+highest_cur_seq_no = 0;
+for (i = 0; i < c->n_playlists; i++) {
+struct playlist *pls = c->playlists[i];
+if (!pls->parsed)
+continue;
+if (pls->cur_seq_no > highest_cur_seq_no)
+highest_cur_seq_no = pls->cur_seq_no;
+}
+if (!pls->finished && 

Re: [FFmpeg-devel] [PATCH] matroskadec: partly revert "demux relevant subtitle packets after a seek" c16582579b1c6f66a86615c5808cd5b2bf17be73

2016-12-02 Thread Rainer Hochecker
absolutely. thanks!
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] matroskadec: partly revert "demux relevant subtitle packets after a seek" c16582579b1c6f66a86615c5808cd5b2bf17be73

2016-11-30 Thread Rainer Hochecker
We already included this patch in Kodi v17. Dropping this incomplete
feature is much better than living with the downsides. Having files on a
network share is a common use case and in most cases there is no index
anyway: start video and seek forward.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] matroskadec: partly revert "demux relevant subtitle packets after a seek" c16582579b1c6f66a86615c5808cd5b2bf17be73

2016-11-26 Thread Rainer Hochecker
From: Rainer Hochecker <fernetme...@online.de>


Alternative patch. Revert the original code because it does more harm than any 
good.


Signed-off-by: Rainer Hochecker <fernetme...@online.de>
---
 libavformat/matroskadec.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index f79511e..cf3de96 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -3398,18 +3398,6 @@ static int matroska_read_seek(AVFormatContext *s, int 
stream_index,
 tracks[i].audio.sub_packet_cnt = 0;
 tracks[i].audio.buf_timecode   = AV_NOPTS_VALUE;
 tracks[i].end_timecode = 0;
-if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE &&
-tracks[i].stream &&
-tracks[i].stream->discard != AVDISCARD_ALL) {
-index_sub = av_index_search_timestamp(
-tracks[i].stream, st->index_entries[index].timestamp,
-AVSEEK_FLAG_BACKWARD);
-while (index_sub >= 0 &&
-  index_min > 0 &&
-  tracks[i].stream->index_entries[index_sub].pos < 
st->index_entries[index_min].pos &&
-  st->index_entries[index].timestamp - 
tracks[i].stream->index_entries[index_sub].timestamp < 300 / 
matroska->time_scale)
-index_min--;
-}
 }
 
 avio_seek(s->pb, st->index_entries[index_min].pos, SEEK_SET);
-- 
2.9.3

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


Re: [FFmpeg-devel] [PATCH] matroska read_seek: make max diff for last known subtitle configurable

2016-11-25 Thread Rainer Hochecker
I was tempted to submit a patch with this feature deleted. Unfortunately I
was not able to find the original reason
why this was implemented. I am sure there was a good reason and this reason
may still be a good one.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] matroska read_seek: make max diff for last known subtitle configurable

2016-11-24 Thread Rainer Hochecker
From: Rainer Hochecker <fernetme...@online.de>

Allow players to reduce the time read_seek sets the file pos before desired 
position.
Hard coded 30 seconds is a lot and takes several seconds when the source is on
a network share.


Signed-off-by: Rainer Hochecker <fernetme...@online.de>
---
 libavformat/matroskadec.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index f79511e..eb2bc31 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -353,6 +353,9 @@ typedef struct MatroskaDemuxContext {
 
 /* WebM DASH Manifest live flag/ */
 int is_live;
+
+/* set file pos up to 30 seconds before desired timestamp on seek */
+int subtitle_seek_diff;
 } MatroskaDemuxContext;
 
 typedef struct MatroskaBlock {
@@ -3407,7 +3410,7 @@ static int matroska_read_seek(AVFormatContext *s, int 
stream_index,
 while (index_sub >= 0 &&
   index_min > 0 &&
   tracks[i].stream->index_entries[index_sub].pos < 
st->index_entries[index_min].pos &&
-  st->index_entries[index].timestamp - 
tracks[i].stream->index_entries[index_sub].timestamp < 300 / 
matroska->time_scale)
+  st->index_entries[index].timestamp - 
tracks[i].stream->index_entries[index_sub].timestamp < 
matroska->subtitle_seek_diff * 1E9 / matroska->time_scale)
 index_min--;
 }
 }
@@ -3813,9 +3816,17 @@ static int 
webm_dash_manifest_read_packet(AVFormatContext *s, AVPacket *pkt)
 #define OFFSET(x) offsetof(MatroskaDemuxContext, x)
 static const AVOption options[] = {
 { "live", "flag indicating that the input is a live file that only has the 
headers.", OFFSET(is_live), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 
AV_OPT_FLAG_DECODING_PARAM },
+{ "subtitle_seek_diff", "max difference in seconds between desired seek 
pos and last known subtitle pos.", OFFSET(subtitle_seek_diff), AV_OPT_TYPE_INT, 
{.i64 = 30}, 0, 30, AV_OPT_FLAG_DECODING_PARAM },
 { NULL },
 };
 
+static const AVClass matroska_class = {
+.class_name = "matroska,webm demuxer",
+.item_name  = av_default_item_name,
+.option = options,
+.version= LIBAVUTIL_VERSION_INT,
+};
+
 static const AVClass webm_dash_class = {
 .class_name = "WebM DASH Manifest demuxer",
 .item_name  = av_default_item_name,
@@ -3828,6 +3839,7 @@ AVInputFormat ff_matroska_demuxer = {
 .long_name  = NULL_IF_CONFIG_SMALL("Matroska / WebM"),
 .extensions = "mkv,mk3d,mka,mks",
 .priv_data_size = sizeof(MatroskaDemuxContext),
+.priv_class = _class,
 .read_probe = matroska_probe,
 .read_header= matroska_read_header,
 .read_packet= matroska_read_packet,
-- 
2.9.3

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


[FFmpeg-devel] [PATCH] estimate_timings_from_pts - increase retry counter, fixes invalid duration for ts files with hevc codec

2015-11-15 Thread Rainer Hochecker
I got a mpegts file with hevc that fails estimating duration. Increasing number 
of
retries fixes the issue.

Rainer

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

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 251b2c6..f8ddaf7 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2463,7 +2463,7 @@ static void 
estimate_timings_from_bit_rate(AVFormatContext *ic)
 }
 
 #define DURATION_MAX_READ_SIZE 25LL
-#define DURATION_MAX_RETRY 4
+#define DURATION_MAX_RETRY 6
 
 /* only usable for MPEG-PS streams */
 static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
-- 
2.5.0

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


[FFmpeg-devel] [PATCH] hevc - fix split function of parser

2015-09-01 Thread Rainer Hochecker
---
 libavcodec/hevc_parser.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index f970de5..35cace5 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -410,19 +410,30 @@ static int hevc_split(AVCodecContext *avctx, const 
uint8_t *buf, int buf_size)
 {
 const uint8_t *ptr = buf, *end = buf + buf_size;
 uint32_t state = -1;
-int has_ps = 0, nut;
+int has_vps = 0;
+int has_sps = 0;
+int has_pps = 0;
+int nut;
 
 while (ptr < end) {
 ptr = avpriv_find_start_code(ptr, end, );
 if ((state >> 8) != START_CODE)
 break;
 nut = (state >> 1) & 0x3F;
-if (nut >= NAL_VPS && nut <= NAL_PPS)
-has_ps = 1;
-else if (has_ps)
-return ptr - 4 - buf;
-else // no parameter set at the beginning of the stream
-return 0;
+if (nut == NAL_VPS)
+has_vps = 1;
+else if (nut == NAL_SPS)
+has_sps = 1;
+else if (nut == NAL_PPS)
+has_pps = 1;
+else if ((nut != NAL_SEI_PREFIX || has_pps) &&
+  nut != NAL_AUD) {
+if (has_vps && has_sps) {
+while (ptr - 4 > buf && ptr[-5] == 0)
+ptr--;
+return ptr - 4 - buf;
+}
+}
 }
 return 0;
 }
-- 
2.1.4

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


[FFmpeg-devel] [PATCH] hevc - fix split function of parser

2015-09-01 Thread Rainer Hochecker

fix splitting extradata from ts
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] hevc - fix split function of parser

2015-09-01 Thread Rainer Hochecker
Carl Eugen Hoyos  ag.or.at> writes:


> Do you have a sample for us?
> Or an explanation on how to reproduce.

I tested with this sample:
http://www.demo-uhd3d.com/fiche.php?cat=uhd=22

check spec 7.4.2.4.4 Order of NAL units and coded pictures
 and their association to access units

> 
> Sorry if it is just me but isn't the 
> following more readable?
> 
> int a = 0, b = 0, c = 0;

personally I don't like multiple statements on a single line but
feel free to change. I followed the example from h264_parser

> 
> (But please feel free to ignore!)
> 
> Carl Eugen
> 




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


Re: [FFmpeg-devel] [PATCH] x86/swr: fix pack_8ch functions on compilers without aligned stack

2015-05-13 Thread Rainer Hochecker
Carl Eugen Hoyos cehoyos at ag.or.at writes:


 
 That sounds impossible since the patch was pushed as 
 http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=f7ed997a
 
 Carl Eugen
 

Why exactly is that impossible? 
It crashes in ff_pack_8ch_float_to_int32_a_sse2 on Windows. 
Same code, same scenario is fine on other platforms.

Rainer

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


Re: [FFmpeg-devel] [PATCH] x86/swr: fix pack_8ch functions on compilers without aligned stack

2015-05-13 Thread Rainer Hochecker
Michael Niedermayer michaelni at gmx.at writes:


 
 can someone who has ICL/MSVC setup test this please
 failing that, lets apply the patch 
 
 [...]


Kodi crashes on Windows when doing 8 channel conversion. This seems to be the 
source of the problem. 

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


Re: [FFmpeg-devel] [PATCH] x86/swr: fix pack_8ch functions on compilers without aligned stack

2015-05-13 Thread Rainer Hochecker
Hendrik Leppkes h.leppkes at gmail.com writes:

 
 
 Kodi's build script suggests that FFmpeg is build with gcc - this
 crash and fix only ever applied to MSVC/ICL builds.
 

It starts crashing with this commit:
https://github.com/FFmpeg/FFmpeg/commit/37b35feb64e4e0382cd5e4502dbf0f7ff9aa0
b5f

Rainer


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


Re: [FFmpeg-devel] [PATCH] x86/swr: fix pack_8ch functions on compilers without aligned stack

2015-05-13 Thread Rainer Hochecker
Carl Eugen Hoyos cehoyos at ag.or.at writes:

 
 So does adding attribute_align_arg to swr_convert_frame() 
 (and friends?) fix the issue?
 
 Carl Eugen
 


I added it to swr_convert and it does fix the issue here.

Rainer

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


[FFmpeg-devel] (no subject)

2015-05-13 Thread Rainer Hochecker

From 85ea58a3129b1766d44bf1425c6656d7a4f5624c Mon Sep 17 00:00:00 2001
From: Rainer Hochecker fernetme...@online.de
Date: Wed, 13 May 2015 18:21:38 +0200
Subject: [PATCH] swr: fix alignment issue caused by 8ch sse functions

---
 libswresample/swresample.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index 6d13bc5..76b7a84 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -23,6 +23,7 @@
 #include audioconvert.h
 #include libavutil/avassert.h
 #include libavutil/channel_layout.h
+#include libavutil/internal.h
 
 #include float.h
 
@@ -663,8 +664,8 @@ int swr_is_initialized(struct SwrContext *s) {
 return !!s-in_buffer.ch_count;
 }
 
-int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int 
out_count,
-const uint8_t *in_arg [SWR_CH_MAX], int  
in_count){
+int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t 
*out_arg[SWR_CH_MAX], int out_count,
+const uint8_t *in_arg 
[SWR_CH_MAX], int  in_count){
 AudioData * in= s-in;
 AudioData *out= s-out;
 
-- 
2.1.4

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


[FFmpeg-devel] (no subject)

2015-05-13 Thread Rainer Hochecker
[PATCH] swr: fix alignment issue caused by 8ch sse functions

Fix crash when doing 8 ch conversion from apps compiled with MSVS
Thanks to Ronald for giving this hint:
https://ffmpeg.org/pipermail/ffmpeg-devel/2015-May/173049.html
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] vda: fix h64 decoding, vda wants the entire buffer

2015-04-02 Thread Rainer Hochecker
Michael Niedermayer michaelni at gmx.at writes:

 
 could it be that this should be using nal_length_size ?
 
 [...]

I tried nal_length_size and it does not fix the issue. Instead it breaks some
other files. Seems silly VDA does only support 4 byte avcC flavour. The 
patch brakes annexb. Should we add a parameter to AVVDAContext so
that the application can instruct decoder what method to use?


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


[FFmpeg-devel] vda: fix h64 decoding, vda wants the entire buffer

2015-04-01 Thread Rainer Hochecker
vda wants the entire buffer with all info. it has no other means to deliver
picture parameters.
according to documentation start_frame can pass the entire buffer
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] vda: fix h64 decoding, vda wants the entire buffer

2015-04-01 Thread Rainer Hochecker
---
 libavcodec/h264.c |  2 +-
 libavcodec/vda_h264.c | 25 -
 2 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index e8d5120..60f8aa1 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1589,7 +1589,7 @@ again:
 decode_postinit(h, nal_index = nals_needed);
 
 if (h-avctx-hwaccel 
-(ret = h-avctx-hwaccel-start_frame(h-avctx, NULL, 
0))  0)
+(ret = h-avctx-hwaccel-start_frame(h-avctx, buf, 
buf_size))  0)
 return ret;
 if (CONFIG_H264_VDPAU_DECODER 
 h-avctx-codec-capabilities  
CODEC_CAP_HWACCEL_VDPAU)
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index 081c366..d8053cf 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -320,8 +320,15 @@ static int vda_h264_start_frame(AVCodecContext *avctx,
 uint32_t size)
 {
 VDAContext *vda = avctx-internal-hwaccel_priv_data;
+void *tmp;
 
-vda-bitstream_size = 0;
+tmp = av_fast_realloc(vda-bitstream,
+  vda-allocated_size,
+  size);
+
+vda-bitstream = tmp;
+memcpy(vda-bitstream, buffer, size);
+vda-bitstream_size = size;
 
 return 0;
 }
@@ -330,22 +337,6 @@ static int vda_h264_decode_slice(AVCodecContext *avctx,
  const uint8_t *buffer,
  uint32_t size)
 {
-VDAContext *vda   = avctx-internal-hwaccel_priv_data;
-void *tmp;
-
-tmp = av_fast_realloc(vda-bitstream,
-  vda-allocated_size,
-  vda-bitstream_size + size + 4);
-if (!tmp)
-return AVERROR(ENOMEM);
-
-vda-bitstream = tmp;
-
-AV_WB32(vda-bitstream + vda-bitstream_size, size);
-memcpy(vda-bitstream + vda-bitstream_size + 4, buffer, size);
-
-vda-bitstream_size += size + 4;
-
 return 0;
 }
 
-- 
2.1.0

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


Re: [FFmpeg-devel] vda: fix h64 decoding, vda wants the entire buffer

2015-04-01 Thread Rainer Hochecker
Hendrik Leppkes h.leppkes at gmail.com writes:

 
 On Wed, Apr 1, 2015 at 12:40 PM, Rainer Hochecker fernetmenta at 
 online.de 
wrote:
  vda wants the entire buffer with all info. it has no other means to deliver
  picture parameters.
  according to documentation start_frame can pass the entire buffer
 
 This doesn't make much sense. If I follow that argument, then vda
 would never have worked, at all. How is it that it does work for many
 other people, presumably including the author of this code?
 
 - Hendrik
 

Correct, it never worked properly. For that reason we had our own decoder for 
 vda which worked properly with consuming the entire bitstream. I don't know
 why nobody cared about this so far.

//Rainer



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


Re: [FFmpeg-devel] [PATCH] vda: fix h64 decoding, vda wants the entire buffer

2015-04-01 Thread Rainer Hochecker
Michael Niedermayer michaelni at gmx.at writes:

 
 could it be that this should be using nal_length_size ?
 
 [...]


I am quite sure that the fix is correct. Our VDA decoder has always been
working like this.
Further I could not find any info on developer@apple that the current
code is valid. No idea what was the source of information for the original code
here.


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


Re: [FFmpeg-devel] [PATCH] vda: fix h64 decoding, vda wants the entire buffer

2015-04-01 Thread Rainer Hochecker
Carl Eugen Hoyos cehoyos at ag.or.at writes:

 (guessing, needs --enable-libx264)
 $ ffmpeg -f lavfi -i testsrc -pix_fmt yuv420p -t 10 out.mp4
 $ ffmpeg -f lavfi -i testsrc -pix_fmt yuv420p -t 10 out.h264
 
 Carl Eugen
 

my vda decoder does not even open with those generated samples. it fails in 
VDADecoderCreate (not related to this change)



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


[FFmpeg-devel] [PATCH] h264: avoid unnecessary calls to get_format

2015-03-31 Thread Rainer Hochecker
---
 libavcodec/h264_slice.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 80d27e5..9477650 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1417,7 +1417,8 @@ int ff_h264_decode_slice_header(H264Context *h, 
H264Context *h0)
  || h-mb_width  != h-sps.mb_width
  || h-mb_height != h-sps.mb_height * (2 - 
h-sps.frame_mbs_only_flag)
 ));
-if (non_j_pixfmt(h0-avctx-pix_fmt) != non_j_pixfmt(get_pixel_format(h0, 
0)))
+if (h0-avctx-pix_fmt == AV_PIX_FMT_NONE
+|| (non_j_pixfmt(h0-avctx-pix_fmt) != 
non_j_pixfmt(get_pixel_format(h0, 0
 must_reinit = 1;
 
 if (first_slice  av_cmp_q(h-sps.sar, h-avctx-sample_aspect_ratio))
-- 
2.1.0

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


[FFmpeg-devel] [PATCH 1/2] hevc: avoid unnecessary calls to get_format

2015-03-12 Thread Rainer Hochecker
---
 libavcodec/hevc.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index fdbaa28..b52e778 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -280,7 +280,7 @@ static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, 
GetBitContext *gb)
 return 0;
 }
 
-static int set_sps(HEVCContext *s, const HEVCSPS *sps)
+static int set_sps(HEVCContext *s, const HEVCSPS *sps, enum AVPixelFormat 
pix_fmt)
 {
 #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL)
 enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
@@ -304,13 +304,18 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
 #endif
 }
 
-*fmt++ = sps-pix_fmt;
-*fmt = AV_PIX_FMT_NONE;
+if (pix_fmt == AV_PIX_FMT_NONE) {
+*fmt++ = sps-pix_fmt;
+*fmt = AV_PIX_FMT_NONE;
 
-ret = ff_thread_get_format(s-avctx, pix_fmts);
-if (ret  0)
-goto fail;
-s-avctx-pix_fmt = ret;
+ret = ff_thread_get_format(s-avctx, pix_fmts);
+if (ret  0)
+goto fail;
+s-avctx-pix_fmt = ret;
+}
+else {
+s-avctx-pix_fmt = pix_fmt;
+}
 
 ff_set_sar(s-avctx, sps-vui.sar);
 
@@ -420,7 +425,7 @@ static int hls_slice_header(HEVCContext *s)
 sh-no_output_of_prior_pics_flag = 0;
 }
 ff_hevc_clear_refs(s);
-ret = set_sps(s, s-sps);
+ret = set_sps(s, s-sps, AV_PIX_FMT_NONE);
 if (ret  0)
 return ret;
 
@@ -3334,7 +3339,7 @@ static int hevc_update_thread_context(AVCodecContext *dst,
 }
 
 if (s-sps != s0-sps)
-if ((ret = set_sps(s, s0-sps))  0)
+if ((ret = set_sps(s, s0-sps, src-pix_fmt))  0)
 return ret;
 
 s-seq_decode = s0-seq_decode;
@@ -3476,6 +3481,8 @@ static void hevc_decode_flush(AVCodecContext *avctx)
 {
 HEVCContext *s = avctx-priv_data;
 ff_hevc_flush_dpb(s);
+hevc_decode_free(avctx);
+s-context_initialized = 0;
 s-max_ra = INT_MAX;
 }
 
-- 
2.1.0

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


[FFmpeg-devel] [PATCH 2/2] hevc: delay ff_thread_finish_setup for hwaccel

2015-03-12 Thread Rainer Hochecker
---
 libavcodec/hevc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index b52e778..998d58e 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2605,7 +2605,8 @@ static int hevc_frame_start(HEVCContext *s)
 if (ret  0)
 goto fail;
 
-ff_thread_finish_setup(s-avctx);
+if (!s-avctx-hwaccel)
+ff_thread_finish_setup(s-avctx);
 
 return 0;
 
-- 
2.1.0

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


[FFmpeg-devel] hevc: fixes for hwaccel when running frame threaded

2015-03-12 Thread Rainer Hochecker

The first patch avoids unnecessary calls to get_format. We open a new
hw decoder on every call to get_format. hevc seems to do something
different than h264. deleting any provious allocated hw decoders
at the application level results in heap corruption. There may be some other
issue left but the multiple and unnecessary calls to get_format already
bothered us with h264 which should be fixed too.

The second patch avoids a flicker when running dxva frame threaded
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/2] hevc: avoid unnecessary calls to get_format

2015-03-12 Thread Rainer Hochecker
Rainer Hochecker fernetmenta at online.de writes:

hevc_decode_flush(AVCodecContext *avctx)
  {
  HEVCContext *s = avctx-priv_data;
  ff_hevc_flush_dpb(s);
 +hevc_decode_free(avctx);
 +s-context_initialized = 0;
  s-max_ra = INT_MAX;
  }
 

this is a left over from debugging. does not belong to the patch




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


Re: [FFmpeg-devel] [PATCH] pthread: Fix?ff_thread_get_formatissues?when called outside frame decode.

2015-03-10 Thread Rainer Hochecker
Hendrik Leppkes h.leppkes at gmail.com writes:


 
 Just making the ff_thread_finish_setup call in hevc_frame_start
 conditional on !hwaccel should do what the other patches did.
 My code isn't setup to use this path, so someone that does should test
 it and send it.
 
 - Hendrik
 ___

I does not solve my particular problem which is all the pointers to hwaccel.
flush_buffers triggers a return of all video surfaces back to application
but application can't terminate the hw decoder because ffmpeg has still
pointers to hwaccel. 



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


Re: [FFmpeg-devel] [PATCH] pthread: Fix ff_thread_get_formatissues when called outside frame decode.

2015-03-09 Thread Rainer Hochecker
Reimar Döffinger Reimar.Doeffinger at gmx.de writes:

 
 Any reason to believe this patch causes it?
 Because I can't see how it would.
 Maybe it's just a bug with DXVA and multithreading in the HEVC code?
 Can you provide some more information like a stacktrace, possibly using a
tool like DrMemory?

I don't think the patch itself is the root cause of the issue, it just
triggers it. get_format is called 4 times, something seems to get corrupted
in opening our hw decoder.
Do you have an explanation why it works with thread_safe_callbacks set to 1?

I am wondering if hevc misses the multithreading fix done for other codecs:
http://ffmpeg.org/pipermail/ffmpeg-cvslog/2013-March/062620.html

What do you think?


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


Re: [FFmpeg-devel] [PATCH] pthread: Fix ff_thread_get_formatissues when called outside frame decode.

2015-03-08 Thread Rainer Hochecker
Reimar Döffinger Reimar.Doeffinger at gmx.de writes:

I tried this patch with Kodi but did not get very far.

int ff_thread_can_start_frame(AVCodecContext *avctx)
{
PerThreadContext *p = avctx-internal-thread_ctx;
if (avctx-active_thread_typeFF_THREAD_FRAME)
return 0;
av_assert0(!p-main_thread);

It hit this assert and call stack showed avformat_find_stream_info

How can I help progressing this. I want to run hevc frame threaded but
without thread_safe_callback because of DXVA.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] pthread: Fix ff_thread_get_formatissues when called outside frame decode.

2015-03-08 Thread Rainer Hochecker
Reimar Döffinger Reimar.Doeffinger at gmx.de writes:


I have tested this with Kodi. Works with sw decoding. With DXVA it crashes,
looks like heap corruption or the like.
setting thread_safe_callbacks = 1 cures the issue but I get some green
frames at start of playback. 
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] hevc: fix deadlock for frame threading safe callbacks disabled

2015-03-08 Thread Rainer Hochecker
---
 libavcodec/hevc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index fdbaa28..7c7f920 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -307,7 +307,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
 *fmt++ = sps-pix_fmt;
 *fmt = AV_PIX_FMT_NONE;
 
-ret = ff_thread_get_format(s-avctx, pix_fmts);
+ret = ff_get_format(s-avctx, pix_fmts);
 if (ret  0)
 goto fail;
 s-avctx-pix_fmt = ret;
-- 
2.1.0

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


Re: [FFmpeg-devel] [PATCH] hevc: fix deadlock for frame threading safe callbacks disabled

2015-03-08 Thread Rainer Hochecker
Rainer Hochecker fernetmenta at online.de writes:

 
 ---
  libavcodec/hevc.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
 index fdbaa28..7c7f920 100644
 --- a/libavcodec/hevc.c
 +++ b/libavcodec/hevc.c
  at  at  -307,7 +307,7  at  at  static int set_sps(HEVCContext *s,
const HEVCSPS *sps)
  *fmt++ = sps-pix_fmt;
  *fmt = AV_PIX_FMT_NONE;
 
 -ret = ff_thread_get_format(s-avctx, pix_fmts);
 +ret = ff_get_format(s-avctx, pix_fmts);
  if (ret  0)
  goto fail;
  s-avctx-pix_fmt = ret;


this is called from the main thread, hence a requesting the main thread do
the call to get_format results in a hang waiting for the state to be changed
to STATE_SETTING_UP

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


Re: [FFmpeg-devel] [PATCH] hevc: fix deadlock for frame threading safe callbacks disabled

2015-03-08 Thread Rainer Hochecker
Reimar Döffinger Reimar.Doeffinger at gmx.de writes:


 
 I sent an alternative patch pthread: Fix ff_thread_get_format issues
 when called outside frame decode.

right, I didn't see you patch not the other code path.

 However there are additional bugs like update_context calling this and thus
 a single SPS change with n threads resulting in n get_format callbacks,
 all except the first completely pointless (and potentially causing
 issues with implementations that don't ensure that multiple get_format
 are side-effect free).
 As a result I am somewhat hesitant about my patch that would end up
 hiding all these issues.
 

the issue with multiple get_format calls is already present for other codecs.
 
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [libav-devel] [PATCH 2/2] lavf: move internal fields from public to internal context

2015-03-07 Thread Rainer Hochecker
Michael Niedermayer michaelni at gmx.at writes:


 
 ive already applied wm4s patch yesterday, so the next ffmpeg release
 (2.6) should contain avformat_flush()
 
 if further changes are needed please tell me
 
 [...]
 


Thanks for notification. I will switch Kodi to 2.6 this weekend.

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


Re: [FFmpeg-devel] [PATCH] avformat: remove FF_API_ASS_SSA dead code

2014-09-25 Thread Rainer Hochecker
Rainer Hochecker fernetmenta at online.de writes:

 
 It's me again. I got a matroshka sample for which I get ASS subs without
 timestamps (NOPTS_VALUE): 
 https://mega.co.nz/#!dEcRwZ4C!cg_6xlpPlhRN0trGEDH1C-ErJ7gXIe6CUezaEokBSV8 . 
 
 Am I doing anything wrong?
 
 Rainer
 

This file has no timestamps at all. I doubt that it worked before upgrade to
ffmpeg 2.4.
Please ignore my previous post.

Rainer



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


Re: [FFmpeg-devel] [PATCH] avformat: remove FF_API_ASS_SSA dead code

2014-09-25 Thread Rainer Hochecker
Clément Bœsch u at pkh.me writes:

 
 I'm seeing timestamps set in the packets with:
   ffprobe -show_packets -show_data -select_streams s:0
~/samples/Test_File-01.mkv
 
 Same with other streams
 


Thanks, making use of ffprobe was a good idea. Now I see the difference.
With version  2.4 we got one packet with multiple Dialogue: ...
http://paste.ubuntu.com/8426844/
Now we get multiple packets with equal pts. This requires an additional
change for us.
http://paste.ubuntu.com/8426767/

Thanks again,
Rainer

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


Re: [FFmpeg-devel] [PATCH] avformat: remove FF_API_ASS_SSA dead code

2014-09-22 Thread Rainer Hochecker
Clément Bœsch u at pkh.me writes:


  
  +1
 
 Applied
 


We at XBMC got the first complaints about broken subtitles. Why was this
removed?

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


Re: [FFmpeg-devel] [PATCH] avformat: remove FF_API_ASS_SSA dead code

2014-09-22 Thread Rainer Hochecker
Clément Bœsch u at pkh.me writes:
 Hi,
 
 We just made the ASS packets from the Matroska output them verbatim, and
 not hacked with timestamps included into the timestamps.
 
 The packets are now typically broadcastable to libass.
 
 Note that this change has been documented since 2.0; doc/APIchanges states:
 
 2013-04-18 - 7c1a002 - lavf 55.3.100
   The matroska demuxer can now output proper verbatim ASS packets. It will
   become the default starting lavf 56.0.100.
 
 It was also mentioned in the RELEASE_NOTES of 2.4 after the bump:
 http://git.videolan.org/?p=ffmpeg.git;a=blob;f=RELEASE_NOTES;hb=HEAD#l40
 
 I'm sorry about the compatibility break but we had to move on, and I
believe it
 was done in a proper way (slow and documented, while providing benefits
for the
 end user at the same time)
 
 Best regards,
 
 PS: this commit didn't disable the code, it was disabled since last bump,
which
 means in 2.4
 

Hi,

Thank you very much for this explanation and sorry for not having read
release notes properly. subs are not my territory but the maintainer is busy
with real life so I will try to adapt to those changes.

Cheers,
Rainer



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


Re: [FFmpeg-devel] [PATCH] avformat: remove FF_API_ASS_SSA dead code

2014-09-22 Thread Rainer Hochecker
Clément Bœsch u at pkh.me writes:

 
 On Mon, Sep 22, 2014 at 03:12:02PM +, Rainer Hochecker wrote:
 [...]
  Hi,
  
  Thank you very much for this explanation and sorry for not having read
  release notes properly. subs are not my territory but the maintainer is busy
  with real life so I will try to adapt to those changes.
  
 
 Feel free to ask more direct questions.
 
 Basically, the idea is that the matroska demuxer will now output
 AVPacket.data that looks like this:
 
 1,,Wolf main,Cher,,,,,Et les enregistrements de ses ondes
delta ?
 
 instead of:
 
 Dialogue: Marked=0,0:02:42.42,0:02:44.15,Wolf
main,autre,,,,,Toujours rien.
 
 (to take the matroska specs example)
 
 The later had several problems, like including timestamp in a string which
 couldn't be altered without insane hacks at format level. It also dropped
 the ReadOrder fields which is needed to get proper rendering.
 
 [...]
 
 Note that we still use the Dialogue: ... form for internal decoded form
 of the subtitles (what you get into AVSubtitle when calling the decode
 subtitles function on the AVPacket), but I'm working on fixing this. I'll
 try to document that change even more, and compatibility will last for a
 long time again.
 

I only needed to add AV_CODEC_ID_ASS to our handler which already took
AV_CODEC_ID_SSA.
According to the discussion here:
http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-May/157170.html, is it
correct to drop AV_CODEC_ID_SSA?

Regards,
Rainer



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