History

avformat/hls: add #EXT-X-START tag support by prefer_x_start opt

Li Kai committed 4 years ago

Commit df8ad4e1 parent 1af36982 files · +61 −2Browse files

Unified · Split

2 files
  1. doc/demuxers.texi +3 −0
  2. libavformat/hls.c +58 −2
doc/demuxers.texi+3−0
@@ -373,6 +373,9 @@ It accepts the following options: · 372 unmodified lines
373373 @item live_start_index
374374 segment index to start live streams at (negative values are from the end).
375375
376+@item prefer_x_start
377+prefer to use #EXT-X-START if it's in playlist instead of live_start_index.
378+
376379 @item allowed_extensions
377380 ',' separated list of file extensions that hls is allowed to access.
378381
libavformat/hls.c+58−2
@@ -120,6 +120,8 @@ struct playlist { · 119 unmodified lines
120120 enum PlaylistType type;
121121 int64_t target_duration;
122122 int64_t start_seq_no;
123+ int time_offset_flag;
124+ int64_t start_time_offset;
123125 int n_segments;
124126 struct segment **segments;
125127 int needed;
@@ -211,6 +213,7 @@ typedef struct HLSContext { · 85 unmodified lines
211213 int64_t cur_seq_no;
212214 int m3u8_hold_counters;
213215 int live_start_index;
216+ int prefer_x_start;
214217 int first_packet;
215218 int64_t first_timestamp;
216219 int64_t cur_timestamp;
@@ -889,6 +892,21 @@ static int parse_playlist(HLSContext *c, const char *url, · 672 unmodified lines
889892 cur_init_section->key = NULL;
890893 }
891894
895+ } else if (av_strstart(line, "#EXT-X-START:", &ptr)) {
896+ const char *time_offset_value = NULL;
897+ ret = ensure_playlist(c, &pls, url);
898+ if (ret < 0) {
899+ goto fail;
900+ }
901+ if (av_strstart(ptr, "TIME-OFFSET=", &time_offset_value)) {
902+ float offset = strtof(time_offset_value, NULL);
903+ pls->start_time_offset = offset * AV_TIME_BASE;
904+ pls->time_offset_flag = 1;
905+ } else {
906+ av_log(c->ctx, AV_LOG_WARNING, "#EXT-X-START value is"
907+ "invalid, it will be ignored");
908+ continue;
909+ }
892910 } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
893911 if (pls)
894912 pls->finished = 1;
@@ -1722,9 +1740,45 @@ static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls) · 827 unmodified lines
17221740 /* If this is a live stream, start live_start_index segments from the
17231741 * start or end */
17241742 if (c->live_start_index < 0)
1725− return pls->start_seq_no + FFMAX(pls->n_segments + c->live_start_index, 0);
1743+ seq_no = pls->start_seq_no + FFMAX(pls->n_segments +
1744+ c->live_start_index, 0);
17261745 else
1727− return pls->start_seq_no + FFMIN(c->live_start_index, pls->n_segments - 1);
1746+ seq_no = pls->start_seq_no + FFMIN(c->live_start_index,
1747+ pls->n_segments - 1);
1748+
1749+ /* If #EXT-X-START in playlist, need to recalculate */
1750+ if (pls->time_offset_flag && c->prefer_x_start) {
1751+ int64_t start_timestamp;
1752+ int64_t playlist_duration = 0;
1753+ int64_t cur_timestamp = c->cur_timestamp == AV_NOPTS_VALUE ? 0 :
1754+ c->cur_timestamp;
1755+
1756+ for (int i = 0; i < pls->n_segments; i++)
1757+ playlist_duration += pls->segments[i]->duration;
1758+
1759+ /* If the absolute value of TIME-OFFSET exceeds
1760+ * the duration of the playlist, it indicates either the end of the
1761+ * playlist (if positive) or the beginning of the playlist (if
1762+ * negative). */
1763+ if (pls->start_time_offset >=0 &&
1764+ pls->start_time_offset > playlist_duration)
1765+ start_timestamp = cur_timestamp + playlist_duration;
1766+ else if (pls->start_time_offset >= 0 &&
1767+ pls->start_time_offset <= playlist_duration)
1768+ start_timestamp = cur_timestamp + pls->start_time_offset;
1769+ else if (pls->start_time_offset < 0 &&
1770+ pls->start_time_offset < -playlist_duration)
1771+ start_timestamp = cur_timestamp;
1772+ else if (pls->start_time_offset < 0 &&
1773+ pls->start_time_offset > -playlist_duration)
1774+ start_timestamp = cur_timestamp + playlist_duration +
1775+ pls->start_time_offset;
1776+ else
1777+ start_timestamp = cur_timestamp;
1778+
1779+ find_timestamp_in_playlist(c, pls, start_timestamp, &seq_no, NULL);
1780+ }
1781+ return seq_no;
17281782 }
17291783
17301784 /* Otherwise just start on the first segment. */
@@ -2476,6 +2530,8 @@ static int hls_probe(const AVProbeData *p) · 745 unmodified lines
24762530 static const AVOption hls_options[] = {
24772531 {"live_start_index", "segment index to start live streams at (negative values are from the end)",
24782532 OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
2533+ {"prefer_x_start", "prefer to use #EXT-X-START if it's in playlist instead of live_start_index",
2534+ OFFSET(prefer_x_start), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS},
24792535 {"allowed_extensions", "List of file extensions that hls is allowed to access",
24802536 OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
24812537 {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t