--- /dev/null
+diff -u -pr a/ffmpeg.c b/ffmpeg.c
+--- a/ffmpeg.c 2021-10-02 14:03:12.000000000 +0200
++++ b/ffmpeg.c 2021-11-30 17:52:38.171328331 +0100
+@@ -4332,7 +4332,7 @@ static int process_input(int file_index)
+ if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+ pkt_dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts
+- && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE) {
++ && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE && !force_dts_monotonicity) {
+ int64_t delta = pkt_dts - ifile->last_ts;
+ if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
+ delta > 1LL*dts_delta_threshold*AV_TIME_BASE){
+@@ -4360,7 +4360,7 @@ static int process_input(int file_index)
+ if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+ pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
+- !copy_ts) {
++ !copy_ts && !force_dts_monotonicity) {
+ int64_t delta = pkt_dts - ist->next_dts;
+ if (is->iformat->flags & AVFMT_TS_DISCONT) {
+ if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
+@@ -4395,6 +4395,43 @@ static int process_input(int file_index)
+ if (pkt.dts != AV_NOPTS_VALUE)
+ ifile->last_ts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
+
++ if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
++ ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
++ (pkt.pts != AV_NOPTS_VALUE || pkt.dts != AV_NOPTS_VALUE) &&
++ force_dts_monotonicity) {
++ int64_t ff_pts_error = 0;
++ int64_t ff_dts_error = 0;
++ int64_t ff_dts_threshold = av_rescale_q(dts_monotonicity_threshold, AV_TIME_BASE_Q, ist->st->time_base);
++
++ // adjust the incoming packet by the accumulated monotonicity error
++ if (pkt.pts != AV_NOPTS_VALUE) {
++ pkt.pts += ifile->ff_timestamp_monotonicity_offset;
++ if (ist->next_pts != AV_NOPTS_VALUE) {
++ ff_pts_error = av_rescale_q(ist->next_pts, AV_TIME_BASE_Q, ist->st->time_base) - pkt.pts;
++ }
++ }
++ if (pkt.dts != AV_NOPTS_VALUE) {
++ pkt.dts += ifile->ff_timestamp_monotonicity_offset;
++ if (ist->next_dts != AV_NOPTS_VALUE) {
++ ff_dts_error = av_rescale_q(ist->next_dts, AV_TIME_BASE_Q, ist->st->time_base) - pkt.dts;
++ }
++ }
++
++ if (ff_dts_error > 0 || ff_dts_error < (-ff_dts_threshold) || ff_pts_error < (-ff_dts_threshold)) {
++ if (pkt.dts == AV_NOPTS_VALUE /*|| ist->next_dts != AV_NOPTS_VALUE*/) {
++ pkt.pts += ff_pts_error;
++ ifile->ff_timestamp_monotonicity_offset += ff_pts_error;
++ av_log(is, AV_LOG_INFO, "Incoming PTS error %"PRId64", offsetting subsequent timestamps by %"PRId64" to correct\n", ff_pts_error, ifile->ff_timestamp_monotonicity_offset);
++ }
++ else {
++ pkt.pts += ff_dts_error;
++ pkt.dts += ff_dts_error;
++ ifile->ff_timestamp_monotonicity_offset += ff_dts_error;
++ av_log(is, AV_LOG_INFO, "Incoming DTS error %"PRId64", offsetting subsequent timestamps by %"PRId64" to correct\n", ff_dts_error, ifile->ff_timestamp_monotonicity_offset);
++ }
++ }
++ }
++
+ if (debug_ts) {
+ av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n",
+ ifile->ist_index + pkt.stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
+Nur in _ffmpeg-git-2ba896f: ffmpeg.c.orig.
+Nur in _ffmpeg-git-2ba896f: ffmpeg.c.rej.
+diff -u -pr a/ffmpeg.h b/ffmpeg.h
+--- a/ffmpeg.h 2021-10-02 14:03:12.000000000 +0200
++++ b/ffmpeg.h 2021-11-30 17:47:55.128659787 +0100
+@@ -417,6 +417,10 @@ typedef struct InputFile {
+ int joined; /* the thread has been joined */
+ int thread_queue_size; /* maximum number of queued packets */
+ #endif
++
++ // A value added to inbound timestamps to prevent them from going "backward" in cases such as HLS discontinuities
++ int64_t ff_timestamp_monotonicity_offset;
++
+ } InputFile;
+
+ enum forced_keyframes_const {
+@@ -584,6 +588,9 @@ extern float audio_drift_threshold;
+ extern float dts_delta_threshold;
+ extern float dts_error_threshold;
+
++extern int dts_monotonicity_threshold;
++extern int force_dts_monotonicity;
++
+ extern int audio_volume;
+ extern int audio_sync_method;
+ extern int video_sync_method;
+Nur in _ffmpeg-git-2ba896f: ffmpeg.h.orig.
+diff -u -pr a/ffmpeg_opt.c b/ffmpeg_opt.c
+--- a/ffmpeg_opt.c 2021-10-02 14:03:12.000000000 +0200
++++ b/ffmpeg_opt.c 2021-11-30 17:47:55.128659787 +0100
+@@ -99,6 +99,9 @@ float audio_drift_threshold = 0.1;
+ float dts_delta_threshold = 10;
+ float dts_error_threshold = 3600*30;
+
++int dts_monotonicity_threshold = AV_TIME_BASE;
++int force_dts_monotonicity = 0;
++
+ int audio_volume = 256;
+ int audio_sync_method = 0;
+ int video_sync_method = VSYNC_AUTO;
+@@ -1070,6 +1073,7 @@ static int open_input_file(OptionsContex
+ f->recording_time = o->recording_time;
+ f->input_ts_offset = o->input_ts_offset;
+ f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
++ f->ff_timestamp_monotonicity_offset = 0;
+ f->nb_streams = ic->nb_streams;
+ f->rate_emu = o->rate_emu;
+ f->accurate_seek = o->accurate_seek;
+@@ -3404,6 +3408,10 @@ const OptionDef options[] = {
+ { "apad", OPT_STRING | HAS_ARG | OPT_SPEC |
+ OPT_OUTPUT, { .off = OFFSET(apad) },
+ "audio pad", "" },
++ { "force_dts_monotonicity", OPT_BOOL | OPT_EXPERT, { &force_dts_monotonicity },
++ "correct dts monotonicity errors" },
++ { "dts_monotonicity_threshold", HAS_ARG | OPT_INT | OPT_EXPERT, { &dts_monotonicity_threshold },
++ "dts correction threshold for forward jumps", "microseconds" },
+ { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
+ "timestamp discontinuity delta threshold", "threshold" },
+ { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_error_threshold },
+Nur in _ffmpeg-git-2ba896f: ffmpeg_opt.c.orig.