+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 void update_noheader_flag(AVFormatContext *s)
+{
+ HLSContext *c = s->priv_data;
+ int flag_needed = 0;
+ int i;
+
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
+
+ if (pls->has_noheader_flag) {
+ flag_needed = 1;
+ break;
+ }
+ }
+
+ if (flag_needed)
+ s->ctx_flags |= AVFMTCTX_NOHEADER;
+ else
+ s->ctx_flags &= ~AVFMTCTX_NOHEADER;
+}
+