* [FFmpeg-devel] [PATCH 2/3] ffmpeg: review -dts_delta_threshold and -dts_delta_error options
@ 2023-02-11 16:29 Stefano Sabatini
0 siblings, 0 replies; only message in thread
From: Stefano Sabatini @ 2023-02-11 16:29 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Stefano Sabatini
Review handling of -dts_delta_threshold and -dts_delta_error options
in order to simplify a bit the logic and improve logging.
---
fftools/ffmpeg.c | 101 +++++++++++++++++++++++++----------------
fftools/ffmpeg.h | 2 +
fftools/ffmpeg_demux.c | 3 ++
3 files changed, 68 insertions(+), 38 deletions(-)
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 064ec6d4b3..22287f6a5e 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3671,62 +3671,87 @@ 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);
+ char ist_desc[32];
+ snprintf(ist_desc, sizeof(ist_desc), "input stream #%d:%d", ist->file_index, ist->st->index);
+
+#define BASE_TS(ts_) av_ts2timestr(ts_, &AV_TIME_BASE_Q)
+#define PKT_TS(ts_) av_ts2timestr(ts_, &ist->st->time_base)
+
+ av_log(NULL, AV_LOG_TRACE,
+ "ts discontinuity detection on %s pkt_dts:%s pkt_pts:%s next_dts:%s last_ts:%s fmt_discont:%d copy_ts:%d\n",
+ ist_desc, PKT_TS(pkt->dts), PKT_TS(pkt->pts),
+ BASE_TS(ist->next_dts), BASE_TS(ifile->last_ts),
+ 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_ ":%s on %s delta:%s > dts_error_threshold:%s on %s\n", \
+ PKT_TS(ts_), BASE_TS(delta), ist_desc, BASE_TS(ist->dts_error_threshold), ist_desc); \
+ 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)) {
- 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);
- 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;
+ 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) {
+ char fix_delta = 0;
+ int64_t dts_limit = FFMAX(ist->pts, ist->dts) - AV_TIME_BASE/10;
+
+ if (FFABS(delta) > ist->dts_delta_threshold) {
+ av_log(NULL, AV_LOG_DEBUG,
+ "detected dts:%s delta:%s > dts_delta_threshold:%s on %s\n",
+ BASE_TS(pkt_dts), BASE_TS(delta), BASE_TS(ist->dts_delta_threshold),
+ ist_desc);
+ fix_delta = 1;
+ } else if (ist->next_dts != AV_NOPTS_VALUE && pkt_dts < dts_limit) {
+ av_log(NULL, AV_LOG_DEBUG, "detected dts:%s < dts_limit:%s on %s\n",
+ BASE_TS(pkt_dts), BASE_TS(dts_limit), ist_desc);
+ fix_delta = 1;
+ }
+
+ if (fix_delta) {
+ ifile->ts_offset_discont -= delta;
+ 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);
+ av_log(NULL, AV_LOG_DEBUG,
+ "ts delta:%s applied -> ts_offset_discont:%s dts:%s pts:%s on %s\n",
+ BASE_TS(-delta), BASE_TS(ifile->ts_offset_discont),
+ PKT_TS(pkt->dts), PKT_TS(pkt->pts), ist_desc);
+ }
}
- 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 f1412f6446..686d38c934 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -368,6 +368,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 98da0678f5..18f8ed8946 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));
--
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-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-11 16:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-11 16:29 [FFmpeg-devel] [PATCH 2/3] ffmpeg: review -dts_delta_threshold and -dts_delta_error options Stefano Sabatini
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