Skip to content

Commit

Permalink
Patch force dts monotonicity branch (#6)
Browse files Browse the repository at this point in the history
* patch for force_dts_monotonicity option to enforce continuity timestamps

* update travis
  • Loading branch information
devindengloom authored Feb 7, 2022
1 parent a59f59f commit 95931bd
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 6 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ language: c
sudo: false
os:
- linux
- osx
addons:
apt:
packages:
Expand All @@ -12,6 +11,9 @@ compiler:
- clang
- gcc
matrix:
include:
- os: osx
osx_image: xcode13.2
exclude:
- os: osx
compiler: gcc
Expand Down
53 changes: 48 additions & 5 deletions fftools/ffmpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -4398,10 +4398,14 @@ static int process_input(int file_index)
pkt.dts *= ist->ts_scale;

pkt_dts = av_rescale_q_rnd(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
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) {
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 &&
!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){
Expand Down Expand Up @@ -4439,7 +4443,9 @@ 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 &&
!disable_discontinuity_correction) {
!disable_discontinuity_correction &&
!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 ||
Expand Down Expand Up @@ -4477,6 +4483,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 (force_dts_monotonicity &&
(pkt.pts != AV_NOPTS_VALUE || pkt.dts != AV_NOPTS_VALUE) &&
(ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO)
) {
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),
Expand Down
7 changes: 7 additions & 0 deletions fftools/ffmpeg.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,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 {
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions fftools/ffmpeg_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,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;
Expand Down Expand Up @@ -1262,6 +1265,7 @@ static int open_input_file(OptionsContext *o, const char *filename)
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;
Expand Down Expand Up @@ -3499,6 +3503,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 },
Expand Down

0 comments on commit 95931bd

Please sign in to comment.