summaryrefslogtreecommitdiff
path: root/libavformat/hls.c
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2016-07-28 00:00:37 +0300
committerAnssi Hannula <anssi.hannula@iki.fi>2016-07-28 01:24:57 +0300
commit83db3c84fa72e8d4d864ed796438ebfb2ee4bcc3 (patch)
tree1bedabf1b28f4670377e7858f8cdd104750e91c2 /libavformat/hls.c
parent9884f17e343b37aef442fafa05bd0113cdf47087 (diff)
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.
Diffstat (limited to 'libavformat/hls.c')
-rw-r--r--libavformat/hls.c134
1 files changed, 69 insertions, 65 deletions
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 59f5e38f9f..35ece98bb8 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);