[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