Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Stefano Sabatini <stefasab@gmail.com>
To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Subject: Re: [FFmpeg-devel] [PATCH] doc/ffmpeg: extend -dts_delta_threshold option description
Date: Mon, 6 Feb 2023 02:25:23 +0100
Message-ID: <20230206012523.GA338325@mariano> (raw)
In-Reply-To: <29fe7152-55a9-8354-b018-60d4ac6e8681@gyani.pro>

[-- Attachment #1: Type: text/plain, Size: 1910 bytes --]

On date Wednesday 2023-01-25 10:47:20 +0530, Gyan Doshi wrote:
> 
> 
> On 2023-01-25 06:37 am, Stefano Sabatini wrote:
> > ---
> >   doc/ffmpeg.texi | 17 +++++++++++++++--
> >   1 file changed, 15 insertions(+), 2 deletions(-)
> > 
> > diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
> > index 67b3294256..122f7e3387 100644
> > --- a/doc/ffmpeg.texi
> > +++ b/doc/ffmpeg.texi
> > @@ -1823,8 +1823,21 @@ results, but increase memory use and latency.
> >   The default value is 10 seconds.
> > -@item -dts_delta_threshold
> > -Timestamp discontinuity delta threshold.
> > +@item -dts_delta_threshold @var{threshold}
> > +Timestamp discontinuity delta threshold, expressed as a floating point
> > +number of @var{AV_TIME_BASE} units.
> This is a CLI option and those users don't deal with AV_TIME_BASE . More
> useful to say it's in seconds.
> 
> > +
> > +If a timestamp discontinuity is detected whose absolute value is
> > +greater than @var{threshold} * @var{AV_TIME_BASE}, ffmpeg will remove the
> > +discontinuity by decreasing/increasing the current DTS and PTS by the
> > +corresponding delta value.
> 

> Might want to mention that this only applies to AV_FMT_DISCONT demuxers, or
> rather give a few examples, like MPEG-TS, HLS..etc.
> For all other formats that users normally work with, clarify that only
> dts_error_threshold is relevant.


> > +
> > +Timestamp discontinuity correction can be inhibited by setting a big value for
> > +@var{threshold}, and is automatically disabled when employing the
> > +@code{-copy_ts} option.
> 
> For copy_ts, it is still applied for all negative deltas except the
> smallest.

Which is a bit arbitrary.

> 
> Not blocking, but I'm reworking this code at present. Shouldn't really
> affect this patch. See
> https://ffmpeg.org/pipermail/ffmpeg-devel/2023-January/305539.html

Updated (had to review the code to get some clarity on the current
behavior).

Thanks.

[-- Attachment #2: 0002-ffmpeg-review-dts_delta_threshold-and-dts_delta_erro.patch --]
[-- Type: text/x-diff, Size: 12000 bytes --]

From 30ac56a14d66eb25428b71c9211f401f818bd057 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefasab@gmail.com>
Date: Fri, 1 Apr 2011 01:13:35 +0200
Subject: [PATCH 2/2] ffmpeg: review -dts_delta_threshold and -dts_delta_error
 options

Review handling of -dts_delta_threshold and -dts_delta_error options,
specify them as floating point expressed in seconds.

Also, review and simplify logic. Adjust values for tests, since in
some cases the new values does not trigger the correction logic.

PR: https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=8252
---
 doc/ffmpeg.texi             | 36 ++++++++++++++++---
 fftools/ffmpeg.c            | 72 ++++++++++++++++++++-----------------
 fftools/ffmpeg.h            |  2 ++
 fftools/ffmpeg_demux.c      |  3 ++
 tests/fate/filter-audio.mak |  2 +-
 tests/fate/mpeg4.mak        |  2 +-
 6 files changed, 77 insertions(+), 40 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 67b3294256..ffffcdd1d7 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1823,12 +1823,38 @@ results, but increase memory use and latency.
 
 The default value is 10 seconds.
 
-@item -dts_delta_threshold
-Timestamp discontinuity delta threshold.
+@item -dts_delta_threshold @var{threshold}
+Timestamp discontinuity delta threshold, expressed as a floating point
+number of seconds.
+
+The timestamp discontinuity correction enabled by this option is only
+applied to input formats accepting timestamp discontinuity (for which
+the @code{AV_FMT_DISCONT} flag is enabled), e.g. MPEG-TS and HLS, and
+is automatically disabled when employing the @code{-copy_ts} option
+(unless wrapping is detected).
+
+If a timestamp discontinuity is detected whose absolute value is
+greater than @var{threshold}, ffmpeg will remove the discontinuity by
+decreasing/increasing the current DTS and PTS by the corresponding
+delta value.
+
+The default value is 10.
+
 @item -dts_error_threshold @var{seconds}
-Timestamp error delta threshold. This threshold use to discard crazy/damaged
-timestamps and the default is 30 hours which is arbitrarily picked and quite
-conservative.
+Timestamp error delta threshold, expressed as a floating point number
+of seconds.
+
+The timestamp correction enabled by this option is only applied to
+input formats not accepting timestamp discontinuity (for which the
+@code{AV_FMT_DISCONT} flag is not enabled).
+
+If a timestamp discontinuity is detected whose absolute value is
+greater than @var{threshold}, ffmpeg will drop the PTS/DTS timestamp
+value.
+
+The default value is @code{3600*30} (30 hours), which is arbitrarily
+picked and quite conservative.
+
 @item -muxdelay @var{seconds} (@emph{output})
 Set the maximum demux-decode delay.
 @item -muxpreload @var{seconds} (@emph{output})
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index f722ae7632..cc58d98813 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3411,62 +3411,68 @@ static void decode_flush(InputFile *ifile)
 static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist,
                                     AVPacket *pkt)
 {
-    const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT;
+    const int fmt_is_discont = !!(ifile->ctx->iformat->flags & AVFMT_TS_DISCONT);
     int disable_discontinuity_correction = copy_ts;
     int64_t pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q,
                                        AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
 
+    av_log(NULL, AV_LOG_TRACE,
+           "ts discontinuity detection on stream #%d:%d pkt_dts:%s pkt_pts:%s next_dts:%s last_ts:%s fmt_discont:%d copy_ts:%d\n",
+           ist->file_index, ist->st->index,
+           av_ts2timestr(pkt->dts, &ist->st->time_base), av_ts2timestr(pkt->pts, &ist->st->time_base),
+           av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q), av_ts2timestr(ifile->last_ts, &AV_TIME_BASE_Q),
+           fmt_is_discont, copy_ts);
+
     if (copy_ts && ist->next_dts != AV_NOPTS_VALUE &&
         fmt_is_discont && ist->st->pts_wrap_bits < 60) {
         int64_t wrap_dts = av_rescale_q_rnd(pkt->dts + (1LL<<ist->st->pts_wrap_bits),
                                             ist->st->time_base, AV_TIME_BASE_Q,
                                             AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
-        if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10)
+        if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10) {
             disable_discontinuity_correction = 0;
+            av_log(NULL, AV_LOG_DEBUG,
+                   "wrapped ts detected in copy_ts, enabled discontinuity correction\n");
+        }
     }
 
-    if (ist->next_dts != AV_NOPTS_VALUE && !disable_discontinuity_correction) {
-        int64_t delta = pkt_dts - ist->next_dts;
+#define CHECK_INVALID_TS(delta_, ts_type_, ts_)                         \
+    if (FFABS(delta_) > ist->dts_error_threshold) {                     \
+        av_log(NULL, AV_LOG_WARNING, "drop invalid " #ts_type_ " ts:%s delta:%s > dts_error_threshold:%s\n", \
+               av_ts2timestr(ts_, &ist->st->time_base),                 \
+               av_ts2timestr(delta_, &AV_TIME_BASE_Q),                  \
+               av_ts2timestr(ist->dts_error_threshold, &AV_TIME_BASE_Q)); \
+        ts_ = AV_NOPTS_VALUE;                                           \
+    }
+
+    if (!disable_discontinuity_correction) {
+        int64_t delta;
+
         if (fmt_is_discont) {
-            if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE ||
-                pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) {
+            delta =
+                ist->next_dts != AV_NOPTS_VALUE ? pkt_dts - ist->next_dts :
+                ifile->last_ts != AV_NOPTS_VALUE ? pkt_dts - ifile->last_ts :
+                AV_NOPTS_VALUE;
+
+            if (delta != AV_NOPTS_VALUE && FFABS(delta) > ist->dts_delta_threshold) {
                 ifile->ts_offset_discont -= delta;
                 av_log(NULL, AV_LOG_DEBUG,
-                       "timestamp discontinuity for stream #%d:%d "
-                       "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n",
-                       ist->file_index, ist->st->index, ist->st->id,
-                       av_get_media_type_string(ist->par->codec_type),
-                       delta, ifile->ts_offset_discont);
+                       "ts offset corrected ts_offset_discont:%s delta:%s > dts_delta_threshold:%s\n",
+                       av_ts2timestr(ifile->ts_offset_discont, &AV_TIME_BASE_Q),
+                       av_ts2timestr(delta, &AV_TIME_BASE_Q),
+                       av_ts2timestr(ist->dts_delta_threshold, &AV_TIME_BASE_Q));
                 pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
                 if (pkt->pts != AV_NOPTS_VALUE)
                     pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
             }
-        } else {
-            if (FFABS(delta) > 1LL * dts_error_threshold * AV_TIME_BASE) {
-                av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt->dts, ist->next_dts, pkt->stream_index);
-                pkt->dts = AV_NOPTS_VALUE;
-            }
-            if (pkt->pts != AV_NOPTS_VALUE){
+        } else if (ist->next_dts != AV_NOPTS_VALUE) {
+            delta = pkt_dts - ist->next_dts;
+            CHECK_INVALID_TS(delta, dts, pkt->dts);
+            if (pkt->pts != AV_NOPTS_VALUE) {
                 int64_t pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
                 delta = pkt_pts - ist->next_dts;
-                if (FFABS(delta) > 1LL * dts_error_threshold * AV_TIME_BASE) {
-                    av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt->pts, ist->next_dts, pkt->stream_index);
-                    pkt->pts = AV_NOPTS_VALUE;
-                }
+                CHECK_INVALID_TS(delta, pts, pkt->pts);
             }
         }
-    } else if (ist->next_dts == AV_NOPTS_VALUE && !copy_ts &&
-               fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) {
-        int64_t delta = pkt_dts - ifile->last_ts;
-        if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) {
-            ifile->ts_offset_discont -= delta;
-            av_log(NULL, AV_LOG_DEBUG,
-                   "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
-                   delta, ifile->ts_offset_discont);
-            pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
-            if (pkt->pts != AV_NOPTS_VALUE)
-                pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
-        }
     }
 
     ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 5527dbe49b..14ad1a10ee 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -352,6 +352,8 @@ typedef struct InputStream {
     int64_t       next_pts;  ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
     int64_t       pts;       ///< current pts of the decoded frame  (in AV_TIME_BASE units)
     int           wrap_correction_done;
+    int64_t       dts_delta_threshold; ///< dts_delta_threshold value rescaled to AV_TIME_BASE units
+    int64_t       dts_error_threshold; ///< dts_error_threshold value rescaled to AV_TIME_BASE units
 
     // the value of AVCodecParserContext.repeat_pict from the AVStream parser
     // for the last packet returned from ifile_get_packet()
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 71ce7d9a02..c7323c4adc 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -736,6 +736,9 @@ static void add_input_streams(const OptionsContext *o, Demuxer *d)
         ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
         ist->prev_pkt_pts = AV_NOPTS_VALUE;
 
+        ist->dts_delta_threshold = 1LL * dts_delta_threshold * AV_TIME_BASE;
+        ist->dts_error_threshold = 1LL * dts_error_threshold * AV_TIME_BASE;
+
         ist->dec_ctx = avcodec_alloc_context3(ist->dec);
         if (!ist->dec_ctx)
             report_and_exit(AVERROR(ENOMEM));
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index eff32b9f81..a0d8a78cb4 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -220,7 +220,7 @@ tests/data/hls-list-append.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data
         -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f segment -segment_time 10 -map 0 -flags +bitexact -codec:a mp2fixed \
         -segment_list $(TARGET_PATH)/$@ -y $(TARGET_PATH)/tests/data/hls-append-out-%03d.ts 2>/dev/null; \
         $(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin \
-        -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_time 10 -map 0 -flags +bitexact \
+        -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_time 10 -map 0 -flags +bitexact -dts_delta_threshold 1 \
         -hls_flags append_list -codec:a mp2fixed -hls_segment_filename $(TARGET_PATH)/tests/data/hls-append-out-%03d.ts \
         $(TARGET_PATH)/tests/data/hls-list-append.m3u8 2>/dev/null
 
diff --git a/tests/fate/mpeg4.mak b/tests/fate/mpeg4.mak
index 4cec21c547..ece5829aee 100644
--- a/tests/fate/mpeg4.mak
+++ b/tests/fate/mpeg4.mak
@@ -1,7 +1,7 @@
 
 MPEG4_RESOLUTION_CHANGE = down-down down-up up-down up-up
 
-fate-mpeg4-resolution-change-%: CMD = framemd5 -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg4/resize_$(@:fate-mpeg4-resolution-change-%=%).h263 -sws_flags +bitexact
+fate-mpeg4-resolution-change-%: CMD = framemd5 -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg4/resize_$(@:fate-mpeg4-resolution-change-%=%).h263 -sws_flags +bitexact -dts_delta_threshold 1
 
 FATE_MPEG4-$(call FRAMEMD5, M4V, MPEG4, SCALE_FILTER) := $(addprefix fate-mpeg4-resolution-change-, $(MPEG4_RESOLUTION_CHANGE))
 
-- 
2.25.1


[-- Attachment #3: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  reply	other threads:[~2023-02-06  1:25 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-25  1:07 Stefano Sabatini
2023-01-25  5:17 ` Gyan Doshi
2023-02-06  1:25   ` Stefano Sabatini [this message]
2023-02-06  4:31     ` Gyan Doshi
2023-02-08 23:41     ` Michael Niedermayer
2023-02-11  2:30       ` Stefano Sabatini
2023-02-11 16:28         ` Stefano Sabatini
2023-02-11 16:56           ` Gyan Doshi
2023-02-20 17:57         ` Anton Khirnov
2023-02-28 21:32           ` Stefano Sabatini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230206012523.GA338325@mariano \
    --to=stefasab@gmail.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git