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.
>From 30ac56a14d66eb25428b71c9211f401f818bd057 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefa...@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

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

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

Reply via email to