Lines Matching defs:pls
192 static void free_segment_list(struct playlist *pls)
195 for (i = 0; i < pls->n_segments; i++) {
196 av_free(pls->segments[i]->key);
197 av_free(pls->segments[i]->url);
198 av_free(pls->segments[i]);
200 av_freep(&pls->segments);
201 pls->n_segments = 0;
208 struct playlist *pls = c->playlists[i];
209 free_segment_list(pls);
210 av_freep(&pls->renditions);
211 av_freep(&pls->id3_buf);
212 av_dict_free(&pls->id3_initial);
213 ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
214 av_free_packet(&pls->pkt);
215 av_free(pls->pb.buffer);
216 if (pls->input)
217 ffurl_close(pls->input);
218 if (pls->ctx) {
219 pls->ctx->pb = NULL;
220 avformat_close_input(&pls->ctx);
222 av_free(pls);
264 struct playlist *pls = av_mallocz(sizeof(struct playlist));
265 if (!pls)
267 reset_packet(&pls->pkt);
268 ff_make_absolute_url(pls->url, sizeof(pls->url), base, url);
269 pls->seek_timestamp = AV_NOPTS_VALUE;
271 pls->is_id3_timestamped = -1;
272 pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
274 dynarray_add(&c->playlists, &c->n_playlists, pls);
275 return pls;
290 struct playlist *pls;
292 pls = new_playlist(c, url, base);
293 if (!pls)
308 dynarray_add(&var->playlists, &var->n_playlists, pls);
482 static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
484 if (*pls)
488 *pls = c->playlists[c->n_playlists - 1];
492 /* pls = NULL => Master Playlist or parentless Media Playlist
493 * pls = !NULL => parented Media Playlist, playlist+variant allocated */
495 struct playlist *pls, AVIOContext *in)
539 if (pls) {
540 free_segment_list(pls);
541 pls->finished = 0;
542 pls->type = PLS_TYPE_UNSPECIFIED;
570 ret = ensure_playlist(c, &pls, url);
573 pls->target_duration = atoi(ptr) * AV_TIME_BASE;
575 ret = ensure_playlist(c, &pls, url);
578 pls->start_seq_no = atoi(ptr);
580 ret = ensure_playlist(c, &pls, url);
584 pls->type = PLS_TYPE_EVENT;
586 pls->type = PLS_TYPE_VOD;
588 if (pls)
589 pls->finished = 1;
610 if (!pls) {
615 pls = c->playlists[c->n_playlists - 1];
627 int seq = pls->start_seq_no + pls->n_segments;
653 dynarray_add(&pls->segments, &pls->n_segments, seg);
668 if (pls)
669 pls->last_load_time = av_gettime();
684 static int read_from_url(struct playlist *pls, uint8_t *buf, int buf_size,
688 struct segment *seg = pls->segments[pls->cur_seq_no - pls->start_seq_no];
692 buf_size = FFMIN(buf_size, seg->size - pls->cur_seg_offset);
695 ret = ffurl_read_complete(pls->input, buf, buf_size);
697 ret = ffurl_read(pls->input, buf, buf_size);
700 pls->cur_seg_offset += ret;
732 static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata,
739 oldentry = av_dict_get(pls->id3_initial, entry->key, NULL, AV_DICT_MATCH_CASE);
745 if (apic && (pls->ctx->nb_streams != 2 || !pls->ctx->streams[1]->attached_pic.data))
749 int size = pls->ctx->streams[1]->attached_pic.size;
753 if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
761 static void handle_id3(AVIOContext *pb, struct playlist *pls)
768 parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta);
771 pls->id3_mpegts_timestamp = timestamp;
772 pls->id3_offset = 0;
775 if (!pls->id3_found) {
777 av_assert0(!pls->id3_deferred_extra);
778 pls->id3_found = 1;
781 if (pls->ctx->nb_streams)
782 ff_id3v2_parse_apic(pls->ctx, &extra_meta);
785 pls->id3_deferred_extra = extra_meta;
787 av_dict_copy(&pls->ctx->metadata, metadata, 0);
788 pls->id3_initial = metadata;
791 if (!pls->id3_changed && id3_has_changed_values(pls, metadata, apic)) {
792 avpriv_report_missing_feature(pls->ctx, "Changing ID3 metadata in HLS audio elementary stream");
793 pls->id3_changed = 1;
798 if (!pls->id3_deferred_extra)
803 static void intercept_id3(struct playlist *pls, uint8_t *buf,
816 bytes = read_from_url(pls, buf + *len, ID3v2_HEADER_SIZE - *len, READ_COMPLETE);
837 struct segment *seg = pls->segments[pls->cur_seq_no - pls->start_seq_no];
844 av_log(pls->ctx, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
856 pls->id3_buf = av_fast_realloc(pls->id3_buf, &pls->id3_buf_size, id3_buf_pos + taglen);
857 if (!pls->id3_buf)
859 memcpy(pls->id3_buf + id3_buf_pos, buf, tag_got_bytes);
865 av_log(pls->ctx, AV_LOG_DEBUG, "Stripped %d HLS ID3 bytes\n", tag_got_bytes);
869 if (read_from_url(pls, pls->id3_buf + id3_buf_pos, remaining, READ_COMPLETE) != remaining)
872 av_log(pls->ctx, AV_LOG_DEBUG, "Stripped additional %d HLS ID3 bytes\n", remaining);
883 bytes = read_from_url(pls, buf + *len, buf_size - *len, READ_NORMAL);
892 if (pls->id3_buf) {
895 ffio_init_context(&id3ioctx, pls->id3_buf, id3_buf_pos, 0, NULL, NULL, NULL, NULL);
896 handle_id3(&id3ioctx, pls);
899 if (pls->is_id3_timestamped == -1)
900 pls->is_id3_timestamped = (pls->id3_mpegts_timestamp != AV_NOPTS_VALUE);
903 static int open_input(HLSContext *c, struct playlist *pls)
908 struct segment *seg = pls->segments[pls->cur_seq_no - pls->start_seq_no];
932 av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n",
933 seg->url, seg->url_offset, pls->index);
936 ret = ffurl_open(&pls->input, seg->url, AVIO_FLAG_READ,
937 &pls->parent->interrupt_callback, &opts);
941 if (strcmp(seg->key, pls->key_url)) {
944 &pls->parent->interrupt_callback, &opts2) == 0) {
945 if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))
946 != sizeof(pls->key)) {
955 av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
958 ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
964 if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,
965 &pls->parent->interrupt_callback)) < 0)
967 av_opt_set(pls->input->priv_data, "key", key, 0);
968 av_opt_set(pls->input->priv_data, "iv", iv, 0);
970 if ((ret = ffurl_connect(pls->input, &opts)) < 0) {
971 ffurl_close(pls->input);
972 pls->input = NULL;
984 int seekret = ffurl_seek(pls->input, seg->url_offset, SEEK_SET);
986 av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);
988 ffurl_close(pls->input);
989 pls->input = NULL;
996 pls->cur_seg_offset = 0;
1000 static int64_t default_reload_interval(struct playlist *pls)
1002 return pls->n_segments > 0 ?
1003 pls->segments[pls->n_segments - 1]->duration :
1004 pls->target_duration;
1101 static int playlist_in_multiple_variants(HLSContext *c, struct playlist *pls)
1110 if (v->playlists[j] == pls) {
1144 static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls,
1150 for (i = 0; i < pls->ctx->nb_streams; i++) {
1151 AVStream *st = s->streams[pls->stream_offset + i];
1156 for (; rend_idx < pls->n_renditions; rend_idx++) {
1157 struct rendition *rend = pls->renditions[rend_idx];
1169 if (rend_idx >=pls->n_renditions)
1176 static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
1184 *seq_no = pls->start_seq_no;
1188 for (i = 0; i < pls->n_segments; i++) {
1189 int64_t diff = pos + pls->segments[i]->duration - timestamp;
1191 *seq_no = pls->start_seq_no + i;
1194 pos += pls->segments[i]->duration;
1197 *seq_no = pls->start_seq_no + pls->n_segments - 1;
1202 static int select_cur_seq_no(HLSContext *c, struct playlist *pls)
1206 if (!pls->finished && !c->first_packet &&
1207 av_gettime() - pls->last_load_time >= default_reload_interval(pls))
1209 parse_playlist(c, pls->url, pls, NULL);
1214 if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
1215 find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
1219 if (!pls->finished) {
1221 c->cur_seq_no >= pls->start_seq_no &&
1222 c->cur_seq_no < pls->start_seq_no + pls->n_segments)
1231 if (pls->n_segments > 3)
1232 return pls->start_seq_no + pls->n_segments - 3;
1236 return pls->start_seq_no;
1284 struct playlist *pls = c->playlists[i];
1285 if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0)
1319 struct playlist *pls = c->playlists[i];
1322 if (pls->n_segments == 0)
1325 if (!(pls->ctx = avformat_alloc_context())) {
1330 pls->index = i;
1331 pls->needed = 1;
1332 pls->parent = s;
1333 pls->cur_seq_no = select_cur_seq_no(c, pls);
1335 pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
1336 ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
1338 pls->pb.seekable = 0;
1339 ret = av_probe_input_buffer(&pls->pb, &in_fmt, pls->segments[0]->url,
1346 av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url);
1347 avformat_free_context(pls->ctx);
1348 pls->ctx = NULL;
1351 pls->ctx->pb = &pls->pb;
1352 pls->stream_offset = stream_offset;
1353 ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
1357 if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
1358 ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
1359 avformat_queue_attached_pictures(pls->ctx);
1360 ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
1361 pls->id3_deferred_extra = NULL;
1364 pls->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
1365 ret = avformat_find_stream_info(pls->ctx, NULL);
1369 if (pls->is_id3_timestamped == -1)
1373 for (j = 0; j < pls->ctx->nb_streams; j++) {
1375 AVStream *ist = pls->ctx->streams[j];
1382 avcodec_copy_context(st->codec, pls->ctx->streams[j]->codec);
1384 if (pls->is_id3_timestamped) /* custom timestamps via id3 */
1390 add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
1391 add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
1392 add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
1394 stream_offset += pls->ctx->nb_streams;
1411 struct playlist *pls = v->playlists[j];
1412 int is_shared = playlist_in_multiple_variants(c, pls);
1415 for (k = 0; k < pls->ctx->nb_streams; k++) {
1416 struct AVStream *st = s->streams[pls->stream_offset + k];
1418 ff_program_add_stream_index(s, i, pls->stream_offset + k);
1446 struct playlist *pls = c->playlists[s->streams[i]->id];
1448 pls->cur_needed = 1;
1451 struct playlist *pls = c->playlists[i];
1452 if (pls->cur_needed && !pls->needed) {
1453 pls->needed = 1;
1455 pls->cur_seq_no = select_cur_seq_no(c, pls);
1456 pls->pb.eof_reached = 0;
1459 pls->seek_timestamp = c->cur_timestamp;
1460 pls->seek_flags = AVSEEK_FLAG_ANY;
1461 pls->seek_stream_index = -1;
1463 av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment %d\n", i, pls->cur_seq_no);
1464 } else if (first && !pls->cur_needed && pls->needed) {
1465 if (pls->input)
1466 ffurl_close(pls->input);
1467 pls->input = NULL;
1468 pls->needed = 0;
1476 static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
1478 if (pls->id3_offset >= 0) {
1479 pls->pkt.dts = pls->id3_mpegts_timestamp +
1480 av_rescale_q(pls->id3_offset,
1481 pls->ctx->streams[pls->pkt.stream_index]->time_base,
1483 if (pls->pkt.duration)
1484 pls->id3_offset += pls->pkt.duration;
1486 pls->id3_offset = -1;
1490 pls->pkt.dts = AV_NOPTS_VALUE;
1493 if (pls->pkt.duration)
1494 pls->pkt.duration = av_rescale_q(pls->pkt.duration,
1495 pls->ctx->streams[pls->pkt.stream_index]->time_base,
1498 pls->pkt.pts = AV_NOPTS_VALUE;
1501 static AVRational get_timebase(struct playlist *pls)
1503 if (pls->is_id3_timestamped)
1506 return pls->ctx->streams[pls->pkt.stream_index]->time_base;
1526 struct playlist *pls = c->playlists[i];
1529 if (pls->needed && !pls->pkt.data) {
1533 ret = av_read_frame(pls->ctx, &pls->pkt);
1535 if (!url_feof(&pls->pb) && ret != AVERROR_EOF)
1537 reset_packet(&pls->pkt);
1541 if (pls->is_id3_timestamped && pls->pkt.stream_index == 0) {
1543 fill_timing_for_id3_timestamped_stream(pls);
1547 pls->pkt.dts != AV_NOPTS_VALUE)
1548 c->first_timestamp = av_rescale_q(pls->pkt.dts,
1549 get_timebase(pls), AV_TIME_BASE_Q);
1552 if (pls->seek_timestamp == AV_NOPTS_VALUE)
1555 if (pls->seek_stream_index < 0 ||
1556 pls->seek_stream_index == pls->pkt.stream_index) {
1558 if (pls->pkt.dts == AV_NOPTS_VALUE) {
1559 pls->seek_timestamp = AV_NOPTS_VALUE;
1563 tb = get_timebase(pls);
1564 ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE,
1566 pls->seek_timestamp;
1567 if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY ||
1568 pls->pkt.flags & AV_PKT_FLAG_KEY)) {
1569 pls->seek_timestamp = AV_NOPTS_VALUE;
1573 av_free_packet(&pls->pkt);
1574 reset_packet(&pls->pkt);
1578 if (pls->pkt.data) {
1584 int64_t dts = pls->pkt.dts;
1588 (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0))
1596 struct playlist *pls = c->playlists[minplaylist];
1597 *pkt = pls->pkt;
1598 pkt->stream_index += pls->stream_offset;
1603 pls->ctx->streams[pls->pkt.stream_index]->time_base,
1649 struct playlist *pls = c->playlists[i];
1650 if (stream_index >= pls->stream_offset &&
1651 stream_index - pls->stream_offset < pls->ctx->nb_streams) {
1652 seek_pls = pls;
1667 struct playlist *pls = c->playlists[i];
1668 if (pls->input) {
1669 ffurl_close(pls->input);
1670 pls->input = NULL;
1672 av_free_packet(&pls->pkt);
1673 reset_packet(&pls->pkt);
1674 pls->pb.eof_reached = 0;
1676 pls->pb.buf_end = pls->pb.buf_ptr = pls->pb.buffer;
1678 pls->pb.pos = 0;
1680 ff_read_frame_flush(pls->ctx);
1682 pls->seek_timestamp = seek_timestamp;
1683 pls->seek_flags = flags;
1685 if (pls != seek_pls) {
1687 find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
1691 pls->seek_stream_index = -1;
1692 pls->seek_flags |= AVSEEK_FLAG_ANY;