* [FFmpeg-devel] [PATCH v3] avformat/hls Implement support for using AVSEEK_FLAG_BACKWARD when seeking
[not found] <CANPC24Gqk0NTsztZtE5KADMpr8+PTUoZpB3AaUKi3wh7Lph3Ug@mail.gmail.com>
@ 2022-01-28 18:52 ` Gustav Grusell
2022-01-28 20:23 ` [FFmpeg-devel] [PATCH v4] avformat/hls: " Gustav Grusell
0 siblings, 1 reply; 5+ messages in thread
From: Gustav Grusell @ 2022-01-28 18:52 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Gustav Grusell
Before, seeking in hls streams would always seek to the next keyframe
after the given timestamp. With this fix, if seeking in videostream and
AVSEEK_FLAG_BACKWARD is set, seeking will be to the first keyframe of
the segment containing the given timestamp. This fixes #7485.
Signed-off-by: Gustav Grusell <gustav.grusell@gmail.com>
---
libavformat/hls.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 4568e72cb2..44afdaab42 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1653,7 +1653,8 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
/* if timestamp was in valid range: returns 1 and sets seq_no
* if not: returns 0 and sets seq_no to closest segment */
static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
- int64_t timestamp, int64_t *seq_no)
+ int64_t timestamp, int64_t *seq_no,
+ int64_t *seg_start_ts)
{
int i;
int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
@@ -1668,6 +1669,9 @@ static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
int64_t diff = pos + pls->segments[i]->duration - timestamp;
if (diff > 0) {
*seq_no = pls->start_seq_no + i;
+ if (seg_start_ts) {
+ *seg_start_ts = pos;
+ }
return 1;
}
pos += pls->segments[i]->duration;
@@ -1691,7 +1695,7 @@ static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
* playlist) and this is a complete file, find the matching segment
* by counting durations. */
if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
- find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
+ find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no, NULL);
return seq_no;
}
@@ -2362,7 +2366,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
int i, j;
int stream_subdemuxer_index;
int64_t first_timestamp, seek_timestamp, duration;
- int64_t seq_no;
+ int64_t seq_no, seg_start_ts;
if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
return AVERROR(ENOSYS);
@@ -2372,8 +2376,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
s->streams[stream_index]->time_base.den,
- flags & AVSEEK_FLAG_BACKWARD ?
- AV_ROUND_DOWN : AV_ROUND_UP);
+ AV_ROUND_DOWN);
duration = s->duration == AV_NOPTS_VALUE ?
0 : s->duration;
@@ -2394,9 +2397,16 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
}
/* check if the timestamp is valid for the playlist with the
* specified stream index */
- if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
+ if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no, &seg_start_ts))
return AVERROR(EIO);
+ if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+ flags & AVSEEK_FLAG_BACKWARD && !(flags & AVSEEK_FLAG_ANY)) {
+ /* Seeking to start of segment ensures we seek to a keyframe located
+ * before the given timestamp. */
+ seek_timestamp = seg_start_ts;
+ }
+
/* set segment now so we do not need to search again below */
seek_pls->cur_seq_no = seq_no;
seek_pls->seek_stream_index = stream_subdemuxer_index;
@@ -2423,7 +2433,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
if (pls != seek_pls) {
/* set closest segment seq_no for playlists not handled above */
- find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
+ find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no, NULL);
/* seek the playlist to the given position without taking
* keyframes into account since this playlist does not have the
* specified stream where we should look for the keyframes */
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* [FFmpeg-devel] [PATCH v4] avformat/hls: Implement support for using AVSEEK_FLAG_BACKWARD when seeking
2022-01-28 18:52 ` [FFmpeg-devel] [PATCH v3] avformat/hls Implement support for using AVSEEK_FLAG_BACKWARD when seeking Gustav Grusell
@ 2022-01-28 20:23 ` Gustav Grusell
2022-02-02 16:31 ` Gustav Grusell
2022-02-03 10:20 ` Steven Liu
0 siblings, 2 replies; 5+ messages in thread
From: Gustav Grusell @ 2022-01-28 20:23 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Gustav Grusell
Before, seeking in hls streams would always seek to the next keyframe
after the given timestamp. With this fix, if seeking in videostream and
AVSEEK_FLAG_BACKWARD is set, seeking will be to the first keyframe of
the segment containing the given timestamp. This fixes #7485.
Signed-off-by: Gustav Grusell <gustav.grusell@gmail.com>
---
libavformat/hls.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 4568e72cb2..44afdaab42 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1653,7 +1653,8 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
/* if timestamp was in valid range: returns 1 and sets seq_no
* if not: returns 0 and sets seq_no to closest segment */
static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
- int64_t timestamp, int64_t *seq_no)
+ int64_t timestamp, int64_t *seq_no,
+ int64_t *seg_start_ts)
{
int i;
int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
@@ -1668,6 +1669,9 @@ static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
int64_t diff = pos + pls->segments[i]->duration - timestamp;
if (diff > 0) {
*seq_no = pls->start_seq_no + i;
+ if (seg_start_ts) {
+ *seg_start_ts = pos;
+ }
return 1;
}
pos += pls->segments[i]->duration;
@@ -1691,7 +1695,7 @@ static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
* playlist) and this is a complete file, find the matching segment
* by counting durations. */
if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
- find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
+ find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no, NULL);
return seq_no;
}
@@ -2362,7 +2366,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
int i, j;
int stream_subdemuxer_index;
int64_t first_timestamp, seek_timestamp, duration;
- int64_t seq_no;
+ int64_t seq_no, seg_start_ts;
if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
return AVERROR(ENOSYS);
@@ -2372,8 +2376,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
s->streams[stream_index]->time_base.den,
- flags & AVSEEK_FLAG_BACKWARD ?
- AV_ROUND_DOWN : AV_ROUND_UP);
+ AV_ROUND_DOWN);
duration = s->duration == AV_NOPTS_VALUE ?
0 : s->duration;
@@ -2394,9 +2397,16 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
}
/* check if the timestamp is valid for the playlist with the
* specified stream index */
- if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
+ if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no, &seg_start_ts))
return AVERROR(EIO);
+ if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+ flags & AVSEEK_FLAG_BACKWARD && !(flags & AVSEEK_FLAG_ANY)) {
+ /* Seeking to start of segment ensures we seek to a keyframe located
+ * before the given timestamp. */
+ seek_timestamp = seg_start_ts;
+ }
+
/* set segment now so we do not need to search again below */
seek_pls->cur_seq_no = seq_no;
seek_pls->seek_stream_index = stream_subdemuxer_index;
@@ -2423,7 +2433,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
if (pls != seek_pls) {
/* set closest segment seq_no for playlists not handled above */
- find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
+ find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no, NULL);
/* seek the playlist to the given position without taking
* keyframes into account since this playlist does not have the
* specified stream where we should look for the keyframes */
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [FFmpeg-devel] [PATCH v4] avformat/hls: Implement support for using AVSEEK_FLAG_BACKWARD when seeking
2022-01-28 20:23 ` [FFmpeg-devel] [PATCH v4] avformat/hls: " Gustav Grusell
@ 2022-02-02 16:31 ` Gustav Grusell
2022-02-03 10:20 ` Steven Liu
1 sibling, 0 replies; 5+ messages in thread
From: Gustav Grusell @ 2022-02-02 16:31 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Any comments on this?
cheers,
Gustav
On Fri, Jan 28, 2022 at 9:24 PM Gustav Grusell <gustav.grusell@gmail.com>
wrote:
> Before, seeking in hls streams would always seek to the next keyframe
> after the given timestamp. With this fix, if seeking in videostream and
> AVSEEK_FLAG_BACKWARD is set, seeking will be to the first keyframe of
> the segment containing the given timestamp. This fixes #7485.
>
> Signed-off-by: Gustav Grusell <gustav.grusell@gmail.com>
> ---
> libavformat/hls.c | 24 +++++++++++++++++-------
> 1 file changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 4568e72cb2..44afdaab42 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -1653,7 +1653,8 @@ static void
> add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
> /* if timestamp was in valid range: returns 1 and sets seq_no
> * if not: returns 0 and sets seq_no to closest segment */
> static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
> - int64_t timestamp, int64_t *seq_no)
> + int64_t timestamp, int64_t *seq_no,
> + int64_t *seg_start_ts)
> {
> int i;
> int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
> @@ -1668,6 +1669,9 @@ static int find_timestamp_in_playlist(HLSContext *c,
> struct playlist *pls,
> int64_t diff = pos + pls->segments[i]->duration - timestamp;
> if (diff > 0) {
> *seq_no = pls->start_seq_no + i;
> + if (seg_start_ts) {
> + *seg_start_ts = pos;
> + }
> return 1;
> }
> pos += pls->segments[i]->duration;
> @@ -1691,7 +1695,7 @@ static int64_t select_cur_seq_no(HLSContext *c,
> struct playlist *pls)
> * playlist) and this is a complete file, find the matching segment
> * by counting durations. */
> if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
> - find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
> + find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no,
> NULL);
> return seq_no;
> }
>
> @@ -2362,7 +2366,7 @@ static int hls_read_seek(AVFormatContext *s, int
> stream_index,
> int i, j;
> int stream_subdemuxer_index;
> int64_t first_timestamp, seek_timestamp, duration;
> - int64_t seq_no;
> + int64_t seq_no, seg_start_ts;
>
> if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags &
> AVFMTCTX_UNSEEKABLE))
> return AVERROR(ENOSYS);
> @@ -2372,8 +2376,7 @@ static int hls_read_seek(AVFormatContext *s, int
> stream_index,
>
> seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
>
> s->streams[stream_index]->time_base.den,
> - flags & AVSEEK_FLAG_BACKWARD ?
> - AV_ROUND_DOWN : AV_ROUND_UP);
> + AV_ROUND_DOWN);
>
> duration = s->duration == AV_NOPTS_VALUE ?
> 0 : s->duration;
> @@ -2394,9 +2397,16 @@ static int hls_read_seek(AVFormatContext *s, int
> stream_index,
> }
> /* check if the timestamp is valid for the playlist with the
> * specified stream index */
> - if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls,
> seek_timestamp, &seq_no))
> + if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls,
> seek_timestamp, &seq_no, &seg_start_ts))
> return AVERROR(EIO);
>
> + if (s->streams[stream_index]->codecpar->codec_type ==
> AVMEDIA_TYPE_VIDEO &&
> + flags & AVSEEK_FLAG_BACKWARD && !(flags & AVSEEK_FLAG_ANY)) {
> + /* Seeking to start of segment ensures we seek to a keyframe
> located
> + * before the given timestamp. */
> + seek_timestamp = seg_start_ts;
> + }
> +
> /* set segment now so we do not need to search again below */
> seek_pls->cur_seq_no = seq_no;
> seek_pls->seek_stream_index = stream_subdemuxer_index;
> @@ -2423,7 +2433,7 @@ static int hls_read_seek(AVFormatContext *s, int
> stream_index,
>
> if (pls != seek_pls) {
> /* set closest segment seq_no for playlists not handled above
> */
> - find_timestamp_in_playlist(c, pls, seek_timestamp,
> &pls->cur_seq_no);
> + find_timestamp_in_playlist(c, pls, seek_timestamp,
> &pls->cur_seq_no, NULL);
> /* seek the playlist to the given position without taking
> * keyframes into account since this playlist does not have
> the
> * specified stream where we should look for the keyframes */
> --
> 2.25.1
>
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [FFmpeg-devel] [PATCH v4] avformat/hls: Implement support for using AVSEEK_FLAG_BACKWARD when seeking
2022-01-28 20:23 ` [FFmpeg-devel] [PATCH v4] avformat/hls: " Gustav Grusell
2022-02-02 16:31 ` Gustav Grusell
@ 2022-02-03 10:20 ` Steven Liu
2022-02-09 5:56 ` Steven Liu
1 sibling, 1 reply; 5+ messages in thread
From: Steven Liu @ 2022-02-03 10:20 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu, Gustav Grusell
> 2022年1月29日 上午4:23,Gustav Grusell <gustav.grusell@gmail.com> 写道:
>
> Before, seeking in hls streams would always seek to the next keyframe
> after the given timestamp. With this fix, if seeking in videostream and
> AVSEEK_FLAG_BACKWARD is set, seeking will be to the first keyframe of
> the segment containing the given timestamp. This fixes #7485.
>
> Signed-off-by: Gustav Grusell <gustav.grusell@gmail.com>
> ---
> libavformat/hls.c | 24 +++++++++++++++++-------
> 1 file changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 4568e72cb2..44afdaab42 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -1653,7 +1653,8 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
> /* if timestamp was in valid range: returns 1 and sets seq_no
> * if not: returns 0 and sets seq_no to closest segment */
> static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
> - int64_t timestamp, int64_t *seq_no)
> + int64_t timestamp, int64_t *seq_no,
> + int64_t *seg_start_ts)
> {
> int i;
> int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
> @@ -1668,6 +1669,9 @@ static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
> int64_t diff = pos + pls->segments[i]->duration - timestamp;
> if (diff > 0) {
> *seq_no = pls->start_seq_no + i;
> + if (seg_start_ts) {
> + *seg_start_ts = pos;
> + }
> return 1;
> }
> pos += pls->segments[i]->duration;
> @@ -1691,7 +1695,7 @@ static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
> * playlist) and this is a complete file, find the matching segment
> * by counting durations. */
> if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
> - find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
> + find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no, NULL);
> return seq_no;
> }
>
> @@ -2362,7 +2366,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
> int i, j;
> int stream_subdemuxer_index;
> int64_t first_timestamp, seek_timestamp, duration;
> - int64_t seq_no;
> + int64_t seq_no, seg_start_ts;
>
> if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
> return AVERROR(ENOSYS);
> @@ -2372,8 +2376,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
>
> seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
> s->streams[stream_index]->time_base.den,
> - flags & AVSEEK_FLAG_BACKWARD ?
> - AV_ROUND_DOWN : AV_ROUND_UP);
> + AV_ROUND_DOWN);
>
> duration = s->duration == AV_NOPTS_VALUE ?
> 0 : s->duration;
> @@ -2394,9 +2397,16 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
> }
> /* check if the timestamp is valid for the playlist with the
> * specified stream index */
> - if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
> + if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no, &seg_start_ts))
> return AVERROR(EIO);
>
> + if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> + flags & AVSEEK_FLAG_BACKWARD && !(flags & AVSEEK_FLAG_ANY)) {
> + /* Seeking to start of segment ensures we seek to a keyframe located
> + * before the given timestamp. */
> + seek_timestamp = seg_start_ts;
> + }
> +
> /* set segment now so we do not need to search again below */
> seek_pls->cur_seq_no = seq_no;
> seek_pls->seek_stream_index = stream_subdemuxer_index;
> @@ -2423,7 +2433,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
>
> if (pls != seek_pls) {
> /* set closest segment seq_no for playlists not handled above */
> - find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
> + find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no, NULL);
> /* seek the playlist to the given position without taking
> * keyframes into account since this playlist does not have the
> * specified stream where we should look for the keyframes */
> --
> 2.25.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
LGTM
Thanks
Steven Liu
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [FFmpeg-devel] [PATCH v4] avformat/hls: Implement support for using AVSEEK_FLAG_BACKWARD when seeking
2022-02-03 10:20 ` Steven Liu
@ 2022-02-09 5:56 ` Steven Liu
0 siblings, 0 replies; 5+ messages in thread
From: Steven Liu @ 2022-02-09 5:56 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu, Gustav Grusell
Steven Liu <lq@chinaffmpeg.org> 于2022年2月3日周四 18:22写道:
>
>
>
> > 2022年1月29日 上午4:23,Gustav Grusell <gustav.grusell@gmail.com> 写道:
> >
> > Before, seeking in hls streams would always seek to the next keyframe
> > after the given timestamp. With this fix, if seeking in videostream and
> > AVSEEK_FLAG_BACKWARD is set, seeking will be to the first keyframe of
> > the segment containing the given timestamp. This fixes #7485.
> >
> > Signed-off-by: Gustav Grusell <gustav.grusell@gmail.com>
> > ---
> > libavformat/hls.c | 24 +++++++++++++++++-------
> > 1 file changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/libavformat/hls.c b/libavformat/hls.c
> > index 4568e72cb2..44afdaab42 100644
> > --- a/libavformat/hls.c
> > +++ b/libavformat/hls.c
> > @@ -1653,7 +1653,8 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
> > /* if timestamp was in valid range: returns 1 and sets seq_no
> > * if not: returns 0 and sets seq_no to closest segment */
> > static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
> > - int64_t timestamp, int64_t *seq_no)
> > + int64_t timestamp, int64_t *seq_no,
> > + int64_t *seg_start_ts)
> > {
> > int i;
> > int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
> > @@ -1668,6 +1669,9 @@ static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
> > int64_t diff = pos + pls->segments[i]->duration - timestamp;
> > if (diff > 0) {
> > *seq_no = pls->start_seq_no + i;
> > + if (seg_start_ts) {
> > + *seg_start_ts = pos;
> > + }
> > return 1;
> > }
> > pos += pls->segments[i]->duration;
> > @@ -1691,7 +1695,7 @@ static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
> > * playlist) and this is a complete file, find the matching segment
> > * by counting durations. */
> > if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
> > - find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
> > + find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no, NULL);
> > return seq_no;
> > }
> >
> > @@ -2362,7 +2366,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
> > int i, j;
> > int stream_subdemuxer_index;
> > int64_t first_timestamp, seek_timestamp, duration;
> > - int64_t seq_no;
> > + int64_t seq_no, seg_start_ts;
> >
> > if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
> > return AVERROR(ENOSYS);
> > @@ -2372,8 +2376,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
> >
> > seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
> > s->streams[stream_index]->time_base.den,
> > - flags & AVSEEK_FLAG_BACKWARD ?
> > - AV_ROUND_DOWN : AV_ROUND_UP);
> > + AV_ROUND_DOWN);
> >
> > duration = s->duration == AV_NOPTS_VALUE ?
> > 0 : s->duration;
> > @@ -2394,9 +2397,16 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
> > }
> > /* check if the timestamp is valid for the playlist with the
> > * specified stream index */
> > - if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
> > + if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no, &seg_start_ts))
> > return AVERROR(EIO);
> >
> > + if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> > + flags & AVSEEK_FLAG_BACKWARD && !(flags & AVSEEK_FLAG_ANY)) {
> > + /* Seeking to start of segment ensures we seek to a keyframe located
> > + * before the given timestamp. */
> > + seek_timestamp = seg_start_ts;
> > + }
> > +
> > /* set segment now so we do not need to search again below */
> > seek_pls->cur_seq_no = seq_no;
> > seek_pls->seek_stream_index = stream_subdemuxer_index;
> > @@ -2423,7 +2433,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
> >
> > if (pls != seek_pls) {
> > /* set closest segment seq_no for playlists not handled above */
> > - find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
> > + find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no, NULL);
> > /* seek the playlist to the given position without taking
> > * keyframes into account since this playlist does not have the
> > * specified stream where we should look for the keyframes */
> > --
> > 2.25.1
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> >
>
> LGTM
Applied as e78d0810d1741535c95e5ae0f198977626b1cdff
Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-02-09 5:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <CANPC24Gqk0NTsztZtE5KADMpr8+PTUoZpB3AaUKi3wh7Lph3Ug@mail.gmail.com>
2022-01-28 18:52 ` [FFmpeg-devel] [PATCH v3] avformat/hls Implement support for using AVSEEK_FLAG_BACKWARD when seeking Gustav Grusell
2022-01-28 20:23 ` [FFmpeg-devel] [PATCH v4] avformat/hls: " Gustav Grusell
2022-02-02 16:31 ` Gustav Grusell
2022-02-03 10:20 ` Steven Liu
2022-02-09 5:56 ` Steven Liu
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git