[FFmpeg-cvslog] avformat/hls: Move stream propagation to a separate function

Anssi Hannula git at videolan.org
Thu Jul 28 01:26:38 EEST 2016


ffmpeg | branch: master | Anssi Hannula <anssi.hannula at iki.fi> | Thu Jul 28 00:00:37 2016 +0300| [83db3c84fa72e8d4d864ed796438ebfb2ee4bcc3] | committer: Anssi Hannula

avformat/hls: Move stream propagation to a separate function

Creation of main demuxer streams from subdemuxer streams is moved to
update_streams_from_subdemuxer() which can be called repeatedly.

There should be no functional changes.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=83db3c84fa72e8d4d864ed796438ebfb2ee4bcc3
---

 libavformat/hls.c | 134 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 69 insertions(+), 65 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 59f5e38..35ece98 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1348,25 +1348,6 @@ reload:
     goto restart;
 }
 
-static int playlist_in_multiple_variants(HLSContext *c, struct playlist *pls)
-{
-    int variant_count = 0;
-    int i, j;
-
-    for (i = 0; i < c->n_variants && variant_count < 2; i++) {
-        struct variant *v = c->variants[i];
-
-        for (j = 0; j < v->n_playlists; j++) {
-            if (v->playlists[j] == pls) {
-                variant_count++;
-                break;
-            }
-        }
-    }
-
-    return variant_count >= 2;
-}
-
 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
                                       enum AVMediaType type, const char *group_id)
 {
@@ -1520,11 +1501,65 @@ static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url,
     return AVERROR(EPERM);
 }
 
+static void add_stream_to_programs(AVFormatContext *s, struct playlist *pls, AVStream *stream)
+{
+    HLSContext *c = s->priv_data;
+    int i, j;
+    int bandwidth = -1;
+
+    for (i = 0; i < c->n_variants; i++) {
+        struct variant *v = c->variants[i];
+
+        for (j = 0; j < v->n_playlists; j++) {
+            if (v->playlists[j] != pls)
+                continue;
+
+            av_program_add_stream_index(s, i, stream->index);
+
+            if (bandwidth < 0)
+                bandwidth = v->bandwidth;
+            else if (bandwidth != v->bandwidth)
+                bandwidth = -1; /* stream in multiple variants with different bandwidths */
+        }
+    }
+
+    if (bandwidth >= 0)
+        av_dict_set_int(&stream->metadata, "variant_bitrate", bandwidth, 0);
+}
+
+/* add new subdemuxer streams to our context, if any */
+static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *pls)
+{
+    while (pls->n_main_streams < pls->ctx->nb_streams) {
+        int ist_idx = pls->n_main_streams;
+        AVStream *st = avformat_new_stream(s, NULL);
+        AVStream *ist = pls->ctx->streams[ist_idx];
+
+        if (!st)
+            return AVERROR(ENOMEM);
+
+        st->id = pls->index;
+
+        avcodec_parameters_copy(st->codecpar, ist->codecpar);
+
+        if (pls->is_id3_timestamped) /* custom timestamps via id3 */
+            avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
+        else
+            avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
+
+        dynarray_add(&pls->main_streams, &pls->n_main_streams, st);
+
+        add_stream_to_programs(s, pls, st);
+    }
+
+    return 0;
+}
+
 static int hls_read_header(AVFormatContext *s)
 {
     void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb;
     HLSContext *c = s->priv_data;
-    int ret = 0, i, j;
+    int ret = 0, i;
     int highest_cur_seq_no = 0;
 
     c->ctx                = s;
@@ -1600,6 +1635,17 @@ static int hls_read_header(AVFormatContext *s)
             add_renditions_to_variant(c, var, AVMEDIA_TYPE_SUBTITLE, var->subtitles_group);
     }
 
+    /* Create a program for each variant */
+    for (i = 0; i < c->n_variants; i++) {
+        struct variant *v = c->variants[i];
+        AVProgram *program;
+
+        program = av_new_program(s, i);
+        if (!program)
+            goto fail;
+        av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
+    }
+
     /* Select the starting segments */
     for (i = 0; i < c->n_playlists; i++) {
         struct playlist *pls = c->playlists[i];
@@ -1688,57 +1734,15 @@ static int hls_read_header(AVFormatContext *s)
             av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
 
         /* Create new AVStreams for each stream in this playlist */
-        for (j = 0; j < pls->ctx->nb_streams; j++) {
-            AVStream *st = avformat_new_stream(s, NULL);
-            AVStream *ist = pls->ctx->streams[j];
-            if (!st) {
-                ret = AVERROR(ENOMEM);
-                goto fail;
-            }
-            st->id = i;
-
-            avcodec_parameters_copy(st->codecpar, pls->ctx->streams[j]->codecpar);
-
-            if (pls->is_id3_timestamped) /* custom timestamps via id3 */
-                avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
-            else
-                avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
-
-            dynarray_add(&pls->main_streams, &pls->n_main_streams, st);
-        }
+        ret = update_streams_from_subdemuxer(s, pls);
+        if (ret < 0)
+            goto fail;
 
         add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
         add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
         add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
     }
 
-    /* Create a program for each variant */
-    for (i = 0; i < c->n_variants; i++) {
-        struct variant *v = c->variants[i];
-        AVProgram *program;
-
-        program = av_new_program(s, i);
-        if (!program)
-            goto fail;
-        av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
-
-        for (j = 0; j < v->n_playlists; j++) {
-            struct playlist *pls = v->playlists[j];
-            int is_shared = playlist_in_multiple_variants(c, pls);
-            int k;
-
-            for (k = 0; k < pls->n_main_streams; k++) {
-                struct AVStream *st = pls->main_streams[k];
-
-                av_program_add_stream_index(s, i, st->index);
-
-                /* Set variant_bitrate for streams unique to this variant */
-                if (!is_shared && v->bandwidth)
-                    av_dict_set_int(&st->metadata, "variant_bitrate", v->bandwidth, 0);
-            }
-        }
-    }
-
     return 0;
 fail:
     free_playlist_list(c);



More information about the ffmpeg-cvslog mailing list