[FFmpeg-devel] [PATCH] fixed a bug for hls demuxer when seeking

Anssi Hannula anssi.hannula at iki.fi
Wed Jan 1 23:45:44 CET 2014


16.12.2013 04:55, Deng James kirjoitti:
> The last patch I sent does have memory leak, and I have fixed it in the
> updated patch, which is in the attachment.
> 
> 
> 0001-fixed-a-bug-for-hls-demuxer-when-seeking.patch
> 
> 
> From c2df90139196bc1d6c76a3d597bad842d288c16c Mon Sep 17 00:00:00 2001
> From: James Deng <hugeice at gmail.com>
> Date: Mon, 16 Dec 2013 10:43:33 +0800
> Subject: [PATCH] fixed a bug for hls demuxer when seeking
> 
> when seeking, only check key frame for user-specified stream (passed
> in as a parameter); otherwise the key frame checking logic will be
> broken by audio packets (because usually all audio packets are key
> frames), and give the decoder a non-key frame and cause it to crash

Thanks for the patch.

However, looks to me like the approach you've taken will cause the
variant playlists that do not contain the c->seek_stream_index stream to
be seeked indefinitely, since the code will then never break out from
the while(1) loop. (It may accidentally somewhat work since you are
comparing the global stream_index to variant-specific stream_index,
which is wrong).

I have refactored the seeking code somewhat ("[PATCH 14/18]
avformat/hls: track seeking on a per-playlist basis", not yet applied)
to separate seeking of separate variant playlists (i.e. they have their
own seek_timestamp, seek_flags etc), so your idea should work better on
top of that since the infinite loop will be avoided.

I can do that myself unless you prefer to do it yourself :)


> ---
>  libavformat/hls.c | 32 ++++++++++++++++++--------------
>  1 file changed, 18 insertions(+), 14 deletions(-)
> 
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 471a62d..90a9cee 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -101,6 +101,7 @@ typedef struct HLSContext {
>      int first_packet;
>      int64_t first_timestamp;
>      int64_t seek_timestamp;
> +    int seek_stream_index;
>      int seek_flags;
>      AVIOInterruptCB *interrupt_callback;
>      char *user_agent;                    ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
> @@ -624,6 +625,7 @@ static int hls_read_header(AVFormatContext *s)
>      c->first_packet = 1;
>      c->first_timestamp = AV_NOPTS_VALUE;
>      c->seek_timestamp  = AV_NOPTS_VALUE;
> +    c->seek_stream_index = -1;
>  
>      return 0;
>  fail:
> @@ -702,20 +704,21 @@ start:
>  
>                  if (c->seek_timestamp == AV_NOPTS_VALUE)
>                      break;
> -
> -                if (var->pkt.dts == AV_NOPTS_VALUE) {
> -                    c->seek_timestamp = AV_NOPTS_VALUE;
> -                    break;
> -                }
> -
> -                st = var->ctx->streams[var->pkt.stream_index];
> -                ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE,
> -                                         st->time_base.den, AV_ROUND_DOWN) -
> -                          c->seek_timestamp;
> -                if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||
> -                                     var->pkt.flags & AV_PKT_FLAG_KEY)) {
> -                    c->seek_timestamp = AV_NOPTS_VALUE;
> -                    break;
> +                if ( c->seek_stream_index < 0 || c->seek_stream_index == var->pkt.stream_index ) {
> +                        if (var->pkt.dts == AV_NOPTS_VALUE) {
> +                                c->seek_timestamp = AV_NOPTS_VALUE;
> +                                break;
> +                        }
> +
> +                        st = var->ctx->streams[var->pkt.stream_index];
> +                        ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE,
> +                                                 st->time_base.den, AV_ROUND_DOWN) -
> +                                c->seek_timestamp;
> +                        if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||
> +                                             var->pkt.flags & AV_PKT_FLAG_KEY)) {
> +                                c->seek_timestamp = AV_NOPTS_VALUE;
> +                                break;
> +                        }
>                  }
>                  av_free_packet(&var->pkt);
>                  reset_packet(&var->pkt);
> @@ -786,6 +789,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
>                                         s->streams[stream_index]->time_base.den,
>                                         flags & AVSEEK_FLAG_BACKWARD ?
>                                         AV_ROUND_DOWN : AV_ROUND_UP);
> +    c->seek_stream_index = stream_index;
>      timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE, stream_index >= 0 ?
>                                 s->streams[stream_index]->time_base.den :
>                                 AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
> -- 1.8.1.4


-- 
Anssi Hannula


More information about the ffmpeg-devel mailing list