diff mbox series

[FFmpeg-devel] avformat/hls Implement support for using AVSEEK_FLAG_BACKWARD when seeking

Message ID 20210525125238.325548-1-gustav.grusell@gmail.com
State Superseded
Headers show
Series [FFmpeg-devel] avformat/hls Implement support for using AVSEEK_FLAG_BACKWARD when seeking | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Gustav Grusell May 25, 2021, 12:52 p.m. UTC
Before, seeking in hls streams would always seek to the next keyframe after the given timestamp.
With this fix, if 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 | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Gustav Grusell June 5, 2021, 6:55 a.m. UTC | #1
On Tue, May 25, 2021 at 2:52 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 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 | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 8fc6924c90..fb8c9b071a 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -2197,6 +2197,15 @@ static int hls_read_packet(AVFormatContext *s,
> AVPacket *pkt)
>                          break;
>                      }
>
> +                    /* If AVSEEK_FLAG_BACKWARD set and not
> AVSEEK_FLAG_ANY,
> +                     * we return the first keyframe encountered */
> +                    if (pls->seek_flags & AVSEEK_FLAG_BACKWARD &&
> +                        !(pls->seek_flags & AVSEEK_FLAG_ANY) &&
> +                        pls->pkt->flags & AV_PKT_FLAG_KEY) {
> +                        pls->seek_timestamp = AV_NOPTS_VALUE;
> +                        break;
> +                    }
> +
>                      tb = get_timebase(pls);
>                      ts_diff = av_rescale_rnd(pls->pkt->dts, AV_TIME_BASE,
>                                              tb.den, AV_ROUND_DOWN) -
> --
> 2.25.1
>
>
Are there any further comments on this? If there is anything I can do to
increase the likelihood of getting this accepted please let me know.

Cheers,
Gustav
Valerii Zapodovnikov June 5, 2021, 8:14 a.m. UTC | #2
You forgot to mention #6850. Also you patch was not seen by patchwork.
Please use "git send-email -v2 -1" to send v2 patch. Thanks.
Gustav Grusell June 5, 2021, 12:16 p.m. UTC | #3
Den lör 5 juni 2021 10:14Valerii Zapodovnikov <val.zapod.vz@gmail.com>
skrev:

> You forgot to mention #6850. Also you patch was not seen by patchwork.
> Please use "git send-email -v2 -1" to send v2 patch. Thanks.
>

Thanks, I will take care of this.
Valerii Zapodovnikov June 5, 2021, 4:29 p.m. UTC | #4
BTW, what about #7359?
Gustav Grusell June 5, 2021, 8:23 p.m. UTC | #5
On Sat, Jun 5, 2021 at 6:30 PM Valerii Zapodovnikov <val.zapod.vz@gmail.com>
wrote:

> BTW, what about #7359?
>
> #7359 is not fixed by my patch, but I thought I would look into that after
I get this patch done. I tried the old patch for #7359 but as far as I
could tell it didn't completely solve the problem.

Regarding #6850, I realized my patch doesn't exactly fix it. In the
scenario described in the bug report, ffplay will use byte seek, so code
touched by my patch is not used then. I haven't yet been able to figure out
why the byte seek operation does not work as expected. However, my patch
will allow correct seek to the beginning of the file if ffplay is run with
byte seek disabled (-bytes 0 on the commandline)
diff mbox series

Patch

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 8fc6924c90..fb8c9b071a 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2197,6 +2197,15 @@  static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
                         break;
                     }
 
+                    /* If AVSEEK_FLAG_BACKWARD set and not AVSEEK_FLAG_ANY,
+                     * we return the first keyframe encountered */
+                    if (pls->seek_flags & AVSEEK_FLAG_BACKWARD &&
+                        !(pls->seek_flags & AVSEEK_FLAG_ANY) &&
+                        pls->pkt->flags & AV_PKT_FLAG_KEY) {
+                        pls->seek_timestamp = AV_NOPTS_VALUE;
+                        break;
+                    }
+
                     tb = get_timebase(pls);
                     ts_diff = av_rescale_rnd(pls->pkt->dts, AV_TIME_BASE,
                                             tb.den, AV_ROUND_DOWN) -