diff mbox

[FFmpeg-devel] avformat/hls: fix seek accuracy problem

Message ID 1514888905-30126-1-git-send-email-mymoeyard@gmail.com
State Superseded
Headers show

Commit Message

mymoeyard@gmail.com Jan. 2, 2018, 10:28 a.m. UTC
From: Wu Zhiqiang <mymoeyard@gmail.com>

HLS demuxer seeking use dts instead of pts.
Demuxer skip some frame when dts is before pts in special case.
And it is impossible to re-seek back to start time after playing.
---
 libavformat/hls.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

Comments

Steven Liu Jan. 2, 2018, 10:57 a.m. UTC | #1
2018-01-02 18:28 GMT+08:00  <mymoeyard@gmail.com>:
> From: Wu Zhiqiang <mymoeyard@gmail.com>
>
> HLS demuxer seeking use dts instead of pts.
> Demuxer skip some frame when dts is before pts in special case.
> And it is impossible to re-seek back to start time after playing.
> ---
>  libavformat/hls.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 950cc4c3bd..069e7b06e9 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -2086,6 +2086,7 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
>           * stream */
>          if (pls->needed && !pls->pkt.data) {
>              while (1) {
> +                int64_t pkt_ts;
>                  int64_t ts_diff;
>                  AVRational tb;
>                  ret = av_read_frame(pls->ctx, &pls->pkt);
> @@ -2101,9 +2102,17 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
>                          fill_timing_for_id3_timestamped_stream(pls);
>                      }
>
> +                    if (pls->pkt.pts != AV_NOPTS_VALUE)
> +                        pkt_ts =  pls->pkt.pts;
> +                    else if (pls->pkt.dts != AV_NOPTS_VALUE)
> +                        pkt_ts =  pls->pkt.dts;
> +                    else
> +                        pkt_ts = AV_NOPTS_VALUE;
> +
> +
>                      if (c->first_timestamp == AV_NOPTS_VALUE &&
> -                        pls->pkt.dts       != AV_NOPTS_VALUE)
> -                        c->first_timestamp = av_rescale_q(pls->pkt.dts,
> +                        pkt_ts       != AV_NOPTS_VALUE)
> +                        c->first_timestamp = av_rescale_q(pkt_ts,
>                              get_timebase(pls), AV_TIME_BASE_Q);
>                  }
>
> @@ -2113,15 +2122,16 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
>                  if (pls->seek_stream_index < 0 ||
>                      pls->seek_stream_index == pls->pkt.stream_index) {
>
> -                    if (pls->pkt.dts == AV_NOPTS_VALUE) {
> +                    if (pkt_ts == AV_NOPTS_VALUE) {
>                          pls->seek_timestamp = AV_NOPTS_VALUE;
>                          break;
>                      }
>
>                      tb = get_timebase(pls);
> -                    ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE,
> +                    ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE,
>                                              tb.den, AV_ROUND_DOWN) -
>                              pls->seek_timestamp;
> +
>                      if (ts_diff >= 0 && (pls->seek_flags  & AVSEEK_FLAG_ANY ||
>                                          pls->pkt.flags & AV_PKT_FLAG_KEY)) {
>                          pls->seek_timestamp = AV_NOPTS_VALUE;
> --
> 2.15.0
>


LGTM , This patch can fix ticket : https://trac.ffmpeg.org/ticket/6850


Thanks

Steven
Aman Karmani Jan. 2, 2018, 6:03 p.m. UTC | #2
On Tue, Jan 2, 2018 at 3:05 AM Steven Liu <lingjiujianke@gmail.com> wrote:

> 2018-01-02 18:28 GMT+08:00  <mymoeyard@gmail.com>:
> > From: Wu Zhiqiang <mymoeyard@gmail.com>
> >
> > HLS demuxer seeking use dts instead of pts.
> > Demuxer skip some frame when dts is before pts in special case.
> > And it is impossible to re-seek back to start time after playing.
> > ---
> >  libavformat/hls.c | 18 ++++++++++++++----
> >  1 file changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/libavformat/hls.c b/libavformat/hls.c
> > index 950cc4c3bd..069e7b06e9 100644
> > --- a/libavformat/hls.c
> > +++ b/libavformat/hls.c
> > @@ -2086,6 +2086,7 @@ static int hls_read_packet(AVFormatContext *s,
> AVPacket *pkt)
> >           * stream */
> >          if (pls->needed && !pls->pkt.data) {
> >              while (1) {
> > +                int64_t pkt_ts;
> >                  int64_t ts_diff;
> >                  AVRational tb;
> >                  ret = av_read_frame(pls->ctx, &pls->pkt);
> > @@ -2101,9 +2102,17 @@ static int hls_read_packet(AVFormatContext *s,
> AVPacket *pkt)
> >                          fill_timing_for_id3_timestamped_stream(pls);
> >                      }
> >
> > +                    if (pls->pkt.pts != AV_NOPTS_VALUE)
> > +                        pkt_ts =  pls->pkt.pts;
> > +                    else if (pls->pkt.dts != AV_NOPTS_VALUE)
> > +                        pkt_ts =  pls->pkt.dts;
> > +                    else
> > +                        pkt_ts = AV_NOPTS_VALUE;
> > +
> > +
> >                      if (c->first_timestamp == AV_NOPTS_VALUE &&
> > -                        pls->pkt.dts       != AV_NOPTS_VALUE)
> > -                        c->first_timestamp = av_rescale_q(pls->pkt.dts,
> > +                        pkt_ts       != AV_NOPTS_VALUE)
> > +                        c->first_timestamp = av_rescale_q(pkt_ts,
> >                              get_timebase(pls), AV_TIME_BASE_Q);
> >                  }
> >
> > @@ -2113,15 +2122,16 @@ static int hls_read_packet(AVFormatContext *s,
> AVPacket *pkt)
> >                  if (pls->seek_stream_index < 0 ||
> >                      pls->seek_stream_index == pls->pkt.stream_index) {
> >
> > -                    if (pls->pkt.dts == AV_NOPTS_VALUE) {
> > +                    if (pkt_ts == AV_NOPTS_VALUE) {
> >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> >                          break;
> >                      }
> >
> >                      tb = get_timebase(pls);
> > -                    ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE,
> > +                    ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE,
> >                                              tb.den, AV_ROUND_DOWN) -
> >                              pls->seek_timestamp;
> > +
> >                      if (ts_diff >= 0 && (pls->seek_flags  &
> AVSEEK_FLAG_ANY ||
> >                                          pls->pkt.flags &
> AV_PKT_FLAG_KEY)) {
> >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > --
> > 2.15.0
> >
>
>
> LGTM , This patch can fix ticket : https://trac.ffmpeg.org/ticket/6850
>

LGTM, I've experienced this bug also.


>
> Thanks
>
> Steven
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
mymoeyard@gmail.com Jan. 3, 2018, 3:20 a.m. UTC | #3
On Wed, Jan 3, 2018 at 2:03 AM, Aman Gupta <ffmpeg@tmm1.net> wrote:

> On Tue, Jan 2, 2018 at 3:05 AM Steven Liu <lingjiujianke@gmail.com> wrote:
>
> > 2018-01-02 18:28 GMT+08:00  <mymoeyard@gmail.com>:
> > > From: Wu Zhiqiang <mymoeyard@gmail.com>
> > >
> > > HLS demuxer seeking use dts instead of pts.
> > > Demuxer skip some frame when dts is before pts in special case.
> > > And it is impossible to re-seek back to start time after playing.
> > > ---
> > >  libavformat/hls.c | 18 ++++++++++++++----
> > >  1 file changed, 14 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/libavformat/hls.c b/libavformat/hls.c
> > > index 950cc4c3bd..069e7b06e9 100644
> > > --- a/libavformat/hls.c
> > > +++ b/libavformat/hls.c
> > > @@ -2086,6 +2086,7 @@ static int hls_read_packet(AVFormatContext *s,
> > AVPacket *pkt)
> > >           * stream */
> > >          if (pls->needed && !pls->pkt.data) {
> > >              while (1) {
> > > +                int64_t pkt_ts;
> > >                  int64_t ts_diff;
> > >                  AVRational tb;
> > >                  ret = av_read_frame(pls->ctx, &pls->pkt);
> > > @@ -2101,9 +2102,17 @@ static int hls_read_packet(AVFormatContext *s,
> > AVPacket *pkt)
> > >                          fill_timing_for_id3_timestamped_stream(pls);
> > >                      }
> > >
> > > +                    if (pls->pkt.pts != AV_NOPTS_VALUE)
> > > +                        pkt_ts =  pls->pkt.pts;
> > > +                    else if (pls->pkt.dts != AV_NOPTS_VALUE)
> > > +                        pkt_ts =  pls->pkt.dts;
> > > +                    else
> > > +                        pkt_ts = AV_NOPTS_VALUE;
> > > +
> > > +
> > >                      if (c->first_timestamp == AV_NOPTS_VALUE &&
> > > -                        pls->pkt.dts       != AV_NOPTS_VALUE)
> > > -                        c->first_timestamp =
> av_rescale_q(pls->pkt.dts,
> > > +                        pkt_ts       != AV_NOPTS_VALUE)
> > > +                        c->first_timestamp = av_rescale_q(pkt_ts,
> > >                              get_timebase(pls), AV_TIME_BASE_Q);
> > >                  }
> > >
> > > @@ -2113,15 +2122,16 @@ static int hls_read_packet(AVFormatContext *s,
> > AVPacket *pkt)
> > >                  if (pls->seek_stream_index < 0 ||
> > >                      pls->seek_stream_index == pls->pkt.stream_index) {
> > >
> > > -                    if (pls->pkt.dts == AV_NOPTS_VALUE) {
> > > +                    if (pkt_ts == AV_NOPTS_VALUE) {
> > >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > >                          break;
> > >                      }
> > >
> > >                      tb = get_timebase(pls);
> > > -                    ts_diff = av_rescale_rnd(pls->pkt.dts,
> AV_TIME_BASE,
> > > +                    ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE,
> > >                                              tb.den, AV_ROUND_DOWN) -
> > >                              pls->seek_timestamp;
> > > +
> > >                      if (ts_diff >= 0 && (pls->seek_flags  &
> > AVSEEK_FLAG_ANY ||
> > >                                          pls->pkt.flags &
> > AV_PKT_FLAG_KEY)) {
> > >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > > --
> > > 2.15.0
> > >
> >
> >
> > LGTM , This patch can fix ticket : https://trac.ffmpeg.org/ticket/6850
> >
>
> LGTM, I've experienced this bug also.
>
>
> >
> > Thanks
> >
> > Steven
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
I found another problem of seeking.
Example:http://devimages.apple.com.edgekey.net/
streaming/examples/bipbop_4x3/gear1/prog_index.m3u8,
return EIO error when seek to beginning.
Calculating first_timestamp only using first packet timestamp may cause
problem
when streams have each  different start time.
It is possible that second stream has smaller start time.
I try to fix it by using start_time of AVformatContext.
I am not not sure why not directly use start time.

Thanks
Aman Karmani Jan. 3, 2018, 5 a.m. UTC | #4
On Tue, Jan 2, 2018 at 7:27 PM Wu Zhiqiang <mymoeyard@gmail.com> wrote:

> On Wed, Jan 3, 2018 at 2:03 AM, Aman Gupta <ffmpeg@tmm1.net> wrote:
>
> > On Tue, Jan 2, 2018 at 3:05 AM Steven Liu <lingjiujianke@gmail.com>
> wrote:
> >
> > > 2018-01-02 18:28 GMT+08:00  <mymoeyard@gmail.com>:
> > > > From: Wu Zhiqiang <mymoeyard@gmail.com>
> > > >
> > > > HLS demuxer seeking use dts instead of pts.
> > > > Demuxer skip some frame when dts is before pts in special case.
> > > > And it is impossible to re-seek back to start time after playing.
> > > > ---
> > > >  libavformat/hls.c | 18 ++++++++++++++----
> > > >  1 file changed, 14 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/libavformat/hls.c b/libavformat/hls.c
> > > > index 950cc4c3bd..069e7b06e9 100644
> > > > --- a/libavformat/hls.c
> > > > +++ b/libavformat/hls.c
> > > > @@ -2086,6 +2086,7 @@ static int hls_read_packet(AVFormatContext *s,
> > > AVPacket *pkt)
> > > >           * stream */
> > > >          if (pls->needed && !pls->pkt.data) {
> > > >              while (1) {
> > > > +                int64_t pkt_ts;
> > > >                  int64_t ts_diff;
> > > >                  AVRational tb;
> > > >                  ret = av_read_frame(pls->ctx, &pls->pkt);
> > > > @@ -2101,9 +2102,17 @@ static int hls_read_packet(AVFormatContext *s,
> > > AVPacket *pkt)
> > > >                          fill_timing_for_id3_timestamped_stream(pls);
> > > >                      }
> > > >
> > > > +                    if (pls->pkt.pts != AV_NOPTS_VALUE)
> > > > +                        pkt_ts =  pls->pkt.pts;
> > > > +                    else if (pls->pkt.dts != AV_NOPTS_VALUE)
> > > > +                        pkt_ts =  pls->pkt.dts;
> > > > +                    else
> > > > +                        pkt_ts = AV_NOPTS_VALUE;
> > > > +
> > > > +
> > > >                      if (c->first_timestamp == AV_NOPTS_VALUE &&
> > > > -                        pls->pkt.dts       != AV_NOPTS_VALUE)
> > > > -                        c->first_timestamp =
> > av_rescale_q(pls->pkt.dts,
> > > > +                        pkt_ts       != AV_NOPTS_VALUE)
> > > > +                        c->first_timestamp = av_rescale_q(pkt_ts,
> > > >                              get_timebase(pls), AV_TIME_BASE_Q);
> > > >                  }
> > > >
> > > > @@ -2113,15 +2122,16 @@ static int hls_read_packet(AVFormatContext
> *s,
> > > AVPacket *pkt)
> > > >                  if (pls->seek_stream_index < 0 ||
> > > >                      pls->seek_stream_index ==
> pls->pkt.stream_index) {
> > > >
> > > > -                    if (pls->pkt.dts == AV_NOPTS_VALUE) {
> > > > +                    if (pkt_ts == AV_NOPTS_VALUE) {
> > > >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > > >                          break;
> > > >                      }
> > > >
> > > >                      tb = get_timebase(pls);
> > > > -                    ts_diff = av_rescale_rnd(pls->pkt.dts,
> > AV_TIME_BASE,
> > > > +                    ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE,
> > > >                                              tb.den, AV_ROUND_DOWN) -
> > > >                              pls->seek_timestamp;
> > > > +
> > > >                      if (ts_diff >= 0 && (pls->seek_flags  &
> > > AVSEEK_FLAG_ANY ||
> > > >                                          pls->pkt.flags &
> > > AV_PKT_FLAG_KEY)) {
> > > >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > > > --
> > > > 2.15.0
> > > >
> > >
> > >
> > > LGTM , This patch can fix ticket : https://trac.ffmpeg.org/ticket/6850
> > >
> >
> > LGTM, I've experienced this bug also.
> >
> >
> > >
> > > Thanks
> > >
> > > Steven
> > > _______________________________________________
> > > ffmpeg-devel mailing list
> > > ffmpeg-devel@ffmpeg.org
> > > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> I found another problem of seeking.
> Example:http://devimages.apple.com.edgekey.net/
> streaming/examples/bipbop_4x3/gear1/prog_index.m3u8,
> return EIO error when seek to beginning.


I experienced this problem a few months ago also, and decided to remove the
EIO error. What do you think?

@@ -2240,9 +2239,12 @@ 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)
         return AVERROR(EIO);

+    /* find the closest timestamp */
+    find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no);
+
     /* 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;





> Calculating first_timestamp only using first packet timestamp may cause
> problem
> when streams have each  different start time.
> It is possible that second stream has smaller start time.
> I try to fix it by using start_time of AVformatContext.
> I am not not sure why not directly use start time.
>
> Thanks
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
mymoeyard@gmail.com Jan. 3, 2018, 5:53 a.m. UTC | #5
On Wed, Jan 3, 2018 at 1:00 PM, Aman Gupta <ffmpeg@tmm1.net> wrote:

> On Tue, Jan 2, 2018 at 7:27 PM Wu Zhiqiang <mymoeyard@gmail.com> wrote:
>
> > On Wed, Jan 3, 2018 at 2:03 AM, Aman Gupta <ffmpeg@tmm1.net> wrote:
> >
> > > On Tue, Jan 2, 2018 at 3:05 AM Steven Liu <lingjiujianke@gmail.com>
> > wrote:
> > >
> > > > 2018-01-02 18:28 GMT+08:00  <mymoeyard@gmail.com>:
> > > > > From: Wu Zhiqiang <mymoeyard@gmail.com>
> > > > >
> > > > > HLS demuxer seeking use dts instead of pts.
> > > > > Demuxer skip some frame when dts is before pts in special case.
> > > > > And it is impossible to re-seek back to start time after playing.
> > > > > ---
> > > > >  libavformat/hls.c | 18 ++++++++++++++----
> > > > >  1 file changed, 14 insertions(+), 4 deletions(-)
> > > > >
> > > > > diff --git a/libavformat/hls.c b/libavformat/hls.c
> > > > > index 950cc4c3bd..069e7b06e9 100644
> > > > > --- a/libavformat/hls.c
> > > > > +++ b/libavformat/hls.c
> > > > > @@ -2086,6 +2086,7 @@ static int hls_read_packet(AVFormatContext
> *s,
> > > > AVPacket *pkt)
> > > > >           * stream */
> > > > >          if (pls->needed && !pls->pkt.data) {
> > > > >              while (1) {
> > > > > +                int64_t pkt_ts;
> > > > >                  int64_t ts_diff;
> > > > >                  AVRational tb;
> > > > >                  ret = av_read_frame(pls->ctx, &pls->pkt);
> > > > > @@ -2101,9 +2102,17 @@ static int hls_read_packet(AVFormatContext
> *s,
> > > > AVPacket *pkt)
> > > > >                          fill_timing_for_id3_
> timestamped_stream(pls);
> > > > >                      }
> > > > >
> > > > > +                    if (pls->pkt.pts != AV_NOPTS_VALUE)
> > > > > +                        pkt_ts =  pls->pkt.pts;
> > > > > +                    else if (pls->pkt.dts != AV_NOPTS_VALUE)
> > > > > +                        pkt_ts =  pls->pkt.dts;
> > > > > +                    else
> > > > > +                        pkt_ts = AV_NOPTS_VALUE;
> > > > > +
> > > > > +
> > > > >                      if (c->first_timestamp == AV_NOPTS_VALUE &&
> > > > > -                        pls->pkt.dts       != AV_NOPTS_VALUE)
> > > > > -                        c->first_timestamp =
> > > av_rescale_q(pls->pkt.dts,
> > > > > +                        pkt_ts       != AV_NOPTS_VALUE)
> > > > > +                        c->first_timestamp = av_rescale_q(pkt_ts,
> > > > >                              get_timebase(pls), AV_TIME_BASE_Q);
> > > > >                  }
> > > > >
> > > > > @@ -2113,15 +2122,16 @@ static int hls_read_packet(AVFormatContext
> > *s,
> > > > AVPacket *pkt)
> > > > >                  if (pls->seek_stream_index < 0 ||
> > > > >                      pls->seek_stream_index ==
> > pls->pkt.stream_index) {
> > > > >
> > > > > -                    if (pls->pkt.dts == AV_NOPTS_VALUE) {
> > > > > +                    if (pkt_ts == AV_NOPTS_VALUE) {
> > > > >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > > > >                          break;
> > > > >                      }
> > > > >
> > > > >                      tb = get_timebase(pls);
> > > > > -                    ts_diff = av_rescale_rnd(pls->pkt.dts,
> > > AV_TIME_BASE,
> > > > > +                    ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE,
> > > > >                                              tb.den,
> AV_ROUND_DOWN) -
> > > > >                              pls->seek_timestamp;
> > > > > +
> > > > >                      if (ts_diff >= 0 && (pls->seek_flags  &
> > > > AVSEEK_FLAG_ANY ||
> > > > >                                          pls->pkt.flags &
> > > > AV_PKT_FLAG_KEY)) {
> > > > >                          pls->seek_timestamp = AV_NOPTS_VALUE;
> > > > > --
> > > > > 2.15.0
> > > > >
> > > >
> > > >
> > > > LGTM , This patch can fix ticket : https://trac.ffmpeg.org/
> ticket/6850
> > > >
> > >
> > > LGTM, I've experienced this bug also.
> > >
> > >
> > > >
> > > > Thanks
> > > >
> > > > Steven
> > > > _______________________________________________
> > > > ffmpeg-devel mailing list
> > > > ffmpeg-devel@ffmpeg.org
> > > > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > > >
> > > _______________________________________________
> > > ffmpeg-devel mailing list
> > > ffmpeg-devel@ffmpeg.org
> > > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > >
> > I found another problem of seeking.
> > Example:http://devimages.apple.com.edgekey.net/
> > streaming/examples/bipbop_4x3/gear1/prog_index.m3u8,
> > return EIO error when seek to beginning.
>
>
> I experienced this problem a few months ago also, and decided to remove the
> EIO error. What do you think?
>
> @@ -2240,9 +2239,12 @@ 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)
>          return AVERROR(EIO);
>
> +    /* find the closest timestamp */
> +    find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no);
> +
>      /* 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;
>
>
>
>
>
> > Calculating first_timestamp only using first packet timestamp may cause
> > problem
> > when streams have each  different start time.
> > It is possible that second stream has smaller start time.
> > I try to fix it by using start_time of AVformatContext.
> > I am not not sure why not directly use start time.
> >
> > Thanks
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

I do not want to disable seek-point check.
BTW, i have submitted the patch to fix this:
http://ffmpeg.org/pipermail/ffmpeg-devel/2018-January/223402.html

Thanks
diff mbox

Patch

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 950cc4c3bd..069e7b06e9 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2086,6 +2086,7 @@  static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
          * stream */
         if (pls->needed && !pls->pkt.data) {
             while (1) {
+                int64_t pkt_ts;
                 int64_t ts_diff;
                 AVRational tb;
                 ret = av_read_frame(pls->ctx, &pls->pkt);
@@ -2101,9 +2102,17 @@  static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
                         fill_timing_for_id3_timestamped_stream(pls);
                     }
 
+                    if (pls->pkt.pts != AV_NOPTS_VALUE)
+                        pkt_ts =  pls->pkt.pts;
+                    else if (pls->pkt.dts != AV_NOPTS_VALUE)
+                        pkt_ts =  pls->pkt.dts;
+                    else
+                        pkt_ts = AV_NOPTS_VALUE;
+
+
                     if (c->first_timestamp == AV_NOPTS_VALUE &&
-                        pls->pkt.dts       != AV_NOPTS_VALUE)
-                        c->first_timestamp = av_rescale_q(pls->pkt.dts,
+                        pkt_ts       != AV_NOPTS_VALUE)
+                        c->first_timestamp = av_rescale_q(pkt_ts,
                             get_timebase(pls), AV_TIME_BASE_Q);
                 }
 
@@ -2113,15 +2122,16 @@  static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
                 if (pls->seek_stream_index < 0 ||
                     pls->seek_stream_index == pls->pkt.stream_index) {
 
-                    if (pls->pkt.dts == AV_NOPTS_VALUE) {
+                    if (pkt_ts == AV_NOPTS_VALUE) {
                         pls->seek_timestamp = AV_NOPTS_VALUE;
                         break;
                     }
 
                     tb = get_timebase(pls);
-                    ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE,
+                    ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE,
                                             tb.den, AV_ROUND_DOWN) -
                             pls->seek_timestamp;
+
                     if (ts_diff >= 0 && (pls->seek_flags  & AVSEEK_FLAG_ANY ||
                                         pls->pkt.flags & AV_PKT_FLAG_KEY)) {
                         pls->seek_timestamp = AV_NOPTS_VALUE;