Re: [FFmpeg-devel] [PATCH] avformat/hls: fix seek accuracy problem
On Wed, Jan 3, 2018 at 1:00 PM, Aman Gupta <ffm...@tmm1.net> wrote: > On Tue, Jan 2, 2018 at 7:27 PM Wu Zhiqiang <mymoey...@gmail.com> wrote: > > > On Wed, Jan 3, 2018 at 2:03 AM, Aman Gupta <ffm...@tmm1.net> wrote: > > > > > On Tue, Jan 2, 2018 at 3:05 AM Steven Liu <lingjiujia...@gmail.com> > > wrote: > > > > > > > 2018-01-02 18:28 GMT+08:00 <mymoey...@gmail.com>: > > > > > From: Wu Zhiqiang <mymoey...@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, >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 > > > > > > > > > > &
Re: [FFmpeg-devel] [PATCH] avformat/hls: fix seek accuracy problem
On Wed, Jan 3, 2018 at 2:03 AM, Aman Gupta <ffm...@tmm1.net> wrote: > On Tue, Jan 2, 2018 at 3:05 AM Steven Liu <lingjiujia...@gmail.com> wrote: > > > 2018-01-02 18:28 GMT+08:00 <mymoey...@gmail.com>: > > > From: Wu Zhiqiang <mymoey...@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, >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 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH, V2] avformat/concat: Fix wrong wrapped timestamp
2017年12月30日 下午7:30,"Nicolas George" <geo...@nsup.org>写道: Wu Zhiqiang (2017-12-30): > The command to generate sample video: > > ffmpeg -f lavfi -i testsrc=duration=120 -c:v h264 -profile:v high -level:v > 10 -pix_fmt yuv420p -r 30 -g 30 -c:a aac test.flv > echo -e "file test.flv\nduration 120" > playlist > ffplay -f concat playlist -ss 90 -max_ts_probe 0 > > then seek to time before 30s , the result timestamp is huge and > print:"Invalid timestamps stream" Thanks. I think I understand the problem: it is not that the timestamps are not unwrapped, it is that they are unwrapped twice, because for some reason lavf defaults to parameters tuned for MPEG. See the attached patch. Regards, -- Nicolas George ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Thanks for the patch, it works fine to me. Disable is good enough to prevent unnecessary wrap control. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH, V2] avformat/concat: Fix wrong wrapped timestamp
On Sat, Dec 30, 2017 at 5:19 AM, Carl Eugen Hoyoswrote: > 2017-12-29 18:38 GMT+01:00 Nicolas George : > > > I am sorry, I do not understand what you are saying at all. > > > > Maybe it would help if you were to give a fully detailed of the simplest > > use case you are trying to fix > > Maybe ticket #6908? > > Carl Eugen > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > i am not sure ticket #6908 is the same case. The command to generate sample video: ffmpeg -f lavfi -i testsrc=duration=120 -c:v h264 -profile:v high -level:v 10 -pix_fmt yuv420p -r 30 -g 30 -c:a aac test.flv echo -e "file test.flv\nduration 120" > playlist ffplay -f concat playlist -ss 90 -max_ts_probe 0 then seek to time before 30s , the result timestamp is huge and print:"Invalid timestamps stream" ffmpeg version N-89656-g0c78b6a Copyright (c) 2000-2017 the FFmpeg developers built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609 Thanks ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH, V2] avformat/concat: Fix wrong wrapped timestamp
2017年12月30日 上午12:30,"Nicolas George" <geo...@nsup.org>写道: Wu Zhiqiang (2017-12-30): > Normally pts_wrap_reference is based on the first packet when calling > ff_read_packet, > which will call function update_wrap_reference , in libavformat/utils line > 734: > > if (ref == AV_NOPTS_VALUE) > ref = pkt->pts; > if (st->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 > || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) > return 0; > ref &= (1LL << st->pts_wrap_bits)-1; > > // reference time stamp should be 60 s before first time stamp > pts_wrap_reference = ref - av_rescale(60, st->time_base.den, > st->time_base.num); > > Because concat_read_header and concat_seek do not call ff_read_packet and > open_file does not copy pts_wrap_reference, > it is constant value during playing. > > If demuxing packets like avformat_open_input => avformat_seek_file => > av_read_frame and seek time is larger than 60s, > the constant reference time will be positive value and not indicate the > normal wrap margin. > > Then seeking to time before pts_wrap_reference may generate huge timestamp, > which not expected. Thanks for explaining, but it still does not address my concern. I probably explained it badly. Let me try to rephrase. When an application is reading directly from a file, if I understand correctly, here is what happens: 1. file contains wrapped timestamps; 2. demuxer sets wrapping_bits to enable timestamps correction; 3. demuxer outputs packets with non-monotonic timestamps; 4. lavf sees non-monotonic timestamps; 5. lavf detects wrapping reference; 6. lavf fixes non-monotonic timestamps; 7. lavf returns packets with monotonic timestamps; 8. application sees packets with monotonic timestamps; 9. application has nothing to do at all about wrapping. Is it right? The concat demuxer behaves like any application. Therefore, I can copy-paste and rename: 1. file contains wrapped timestamps; 2. slave demuxer sets wrapping_bits to enable timestamps correction; 3. slave demuxer outputs packets with non-monotonic timestamps; 4. lavf for slave demuxer sees non-monotonic timestamps; 5. lavf for slave demuxer detects wrapping reference; 6. lavf for slave demuxer fixes non-monotonic timestamps; 7. lavf for slave demuxer returns packets with monotonic timestamps; 8. concat sees packets with monotonic timestamps; 9. concat has nothing to do at all about wrapping. And it should still be right. Note the conclusion: concat has nothing to do at all about wrapping. I will try to rephrase yet another way: Wrapped timestamps should be de-wrapped even before concat sees them, and thus no de-wrapping should be necessary after concat. Regards, -- Nicolas George ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel But how to decide wrap margin that concat see? Though monotonic timestamp is always ok, I do not want that sub-demuxer see unwrapped timestamp but concat see wrapped one . Or sub-demuxer disable wrap correction but concat enable it. Thanks ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH, V2] avformat/concat: Fix wrong wrapped timestamp
On Fri, Dec 29, 2017 at 8:00 PM, Nicolas Georgewrote: > Hi. Sorry for having missed your reply earlier. > > 吴志强 (2017-12-18): > > I see wrap timestamp control is enable by pts_wrap_bits(default 33), > > but mp4 demuxer will later set this to 64 (means disabled). > > Now pts_wrap_bits are always tied to 33 without copy it, which seems > > strange. > > I understand the logic of this patch less and less. Why are you speaking > about the MP4 demuxer? > > If I understand correctly how unwrapping timestamp works, concat should > never have to do it. > > > 2017-12-17 22:55 GMT+08:00 Nicolas George : > > Please remember that top-posting on this list is forbidden. If you do > not know what it means, look it up. > > Regards, > > -- > Nicolas George > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > Sorry for top-posting. Normally pts_wrap_reference is based on the first packet when calling ff_read_packet, which will call function update_wrap_reference , in libavformat/utils line 734: if (ref == AV_NOPTS_VALUE) ref = pkt->pts; if (st->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) return 0; ref &= (1LL << st->pts_wrap_bits)-1; // reference time stamp should be 60 s before first time stamp pts_wrap_reference = ref - av_rescale(60, st->time_base.den, st->time_base.num); Because concat_read_header and concat_seek do not call ff_read_packet and open_file does not copy pts_wrap_reference, it is constant value during playing. If demuxing packets like avformat_open_input => avformat_seek_file => av_read_frame and seek time is larger than 60s, the constant reference time will be positive value and not indicate the normal wrap margin. Then seeking to time before pts_wrap_reference may generate huge timestamp, which not expected. Thanks. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel