[FFmpeg-devel] [PATCH] avformat/hls:use EXT-X-START instead of live_start_index if it's in playlist
Steven Liu
lingjiujianke at gmail.com
Fri Jun 24 04:50:53 EEST 2022
<wolfleekay at gmail.com> 于2022年6月23日周四 23:01写道:
>
> From: Li Kai <wolfleekay at gmail.com>
Hi Li,
>
> Refer to https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.5.2
>
> Signed-off-by: Li Kai <wolfleekay at gmail.com>
> ---
> libavformat/hls.c | 68 ++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 62 insertions(+), 6 deletions(-)
>
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 8204f55df3..96923c3eac 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -120,6 +120,8 @@ struct playlist {
> enum PlaylistType type;
> int64_t target_duration;
> int64_t start_seq_no;
> + int time_offset_flag;
> + int64_t start_time_offset;
> int n_segments;
> struct segment **segments;
> int needed;
> @@ -741,6 +743,7 @@ static int parse_playlist(HLSContext *c, const char *url,
> struct segment **prev_segments = NULL;
> int prev_n_segments = 0;
> int64_t prev_start_seq_no = -1;
> + const char *p;
>
> if (is_http && !in && c->http_persistent && c->playlist_pb) {
> in = c->playlist_pb;
> @@ -889,6 +892,18 @@ static int parse_playlist(HLSContext *c, const char *url,
> cur_init_section->key = NULL;
> }
>
> + } else if (av_strstart(line, "#EXT-X-START:", &ptr)) {
> + ret = ensure_playlist(c, &pls, url);
> + if (ret < 0) {
> + goto fail;
> + }
> + if (av_strstart(ptr, "TIME-OFFSET=", &p)) {
> + float offset = strtof(p, NULL);
> + pls->start_time_offset = offset * AV_TIME_BASE;
> + pls->time_offset_flag = 1;
> + } else {
> + goto fail;
> + }
This part is refine hls function, but i prefer reserved old process way bellow.
Support both way of them should be ok.
> } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
> if (pls)
> pls->finished = 1;
> @@ -1719,12 +1734,53 @@ static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
> * require us to download a segment to inspect its timestamps. */
> return c->cur_seq_no;
>
> - /* If this is a live stream, start live_start_index segments from the
> - * start or end */
> - if (c->live_start_index < 0)
> - return pls->start_seq_no + FFMAX(pls->n_segments + c->live_start_index, 0);
> - else
> - return pls->start_seq_no + FFMIN(c->live_start_index, pls->n_segments - 1);
> + if (!pls->time_offset_flag) {
> + /* If this is a live stream, start live_start_index segments from the
> + * start or end */
> + if (c->live_start_index < 0)
This could be set by user from command line.
It's not only used from play list, also can be controled by user.
> + return pls->start_seq_no + FFMAX(pls->n_segments +
> + c->live_start_index, 0);
> + else
> + return pls->start_seq_no + FFMIN(c->live_start_index,
> + pls->n_segments - 1);
> + } else {
> + /* If playlist indicate a TIME-OFFSET, need to recalculate seq_no */
> + int i;
> + int64_t start_timestamp;
> + int64_t playlist_duration = 0;
> + int64_t cur_timestamp = c->cur_timestamp == AV_NOPTS_VALUE ? 0 :
> + c->cur_timestamp;
> +
> + for (i = 0; i < pls->n_segments; i++) {
> + playlist_duration += pls->segments[i]->duration;
> + }
> + /* If the absolute value of TIME-OFFSET exceeds
> + * the duration of the Playlist, it indicates either the end of the
> + * Playlist (if positive) or the beginning of the Playlist (if
> + * negative). */
> + if (pls->start_time_offset >=0 &&
> + pls->start_time_offset > playlist_duration)
> + start_timestamp = cur_timestamp + playlist_duration;
> + else if (pls->start_time_offset >= 0 &&
> + pls->start_time_offset <= playlist_duration)
> + start_timestamp = cur_timestamp + pls->start_time_offset;
> + else if (pls->start_time_offset < 0 &&
> + pls->start_time_offset < -playlist_duration)
> + start_timestamp = cur_timestamp;
> + else if (pls->start_time_offset < 0 &&
> + pls->start_time_offset > -playlist_duration)
> + start_timestamp = cur_timestamp + playlist_duration +
> + pls->start_time_offset;
> + else
> + start_timestamp = cur_timestamp;
> +
> + find_timestamp_in_playlist(c, pls, start_timestamp, &seq_no, NULL);
> + av_log(c, AV_LOG_DEBUG, "start_timestamp: %" PRId64
> + "cur_timestamp:%" PRId64
> + "cur_seq_no:%" PRId64 "\n",
> + start_timestamp, cur_timestamp, seq_no);
> + return seq_no;
> + }
> }
>
> /* Otherwise just start on the first segment. */
> --
> 2.25.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
Thanks
Steven
More information about the ffmpeg-devel
mailing list