From 7474d904ae1cc0e17d39e164d4499d87b143e30e Mon Sep 17 00:00:00 2001
From: withmorten <morten.with@gmail.com>
Date: Sun, 10 Jun 2018 22:46:11 +0200
Subject: [PATCH] fftools/ffmpeg_opt: Add -toeof option to stop reading at
 position relative to EOF

Signed-off-by: Morten With <morten.with@gmail.com>
---
 doc/ffmpeg.texi      |  6 ++++++
 fftools/ffmpeg.h     |  1 +
 fftools/ffmpeg_opt.c | 27 +++++++++++++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 3717f22d42..f627f0e8a5 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -488,6 +488,12 @@ see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1)
 
 -to and -t are mutually exclusive and -t has priority.
 
+@item -toeof @var{position} (@emph{input})
+Stop reading the input at @var{position} relative to the "end of file". That is,
+larger negative values are later in the file, 0 is at EOF.
+
+-toeof and -to, as well as -toeof and -t, are mutually exclusive, and -to, or respectively -t, has priority.
+
 @item -fs @var{limit_size} (@emph{output})
 Set the file size limit, expressed in bytes. No further chunk of bytes is written
 after the limit is exceeded. The size of the output file is slightly more than the
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index eb1eaf6363..70026b376e 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -149,6 +149,7 @@ typedef struct OptionsContext {
 
     int64_t recording_time;
     int64_t stop_time;
+    int64_t stop_time_eof;
     uint64_t limit_filesize;
     float mux_preload;
     float mux_max_delay;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index a2ecddae71..047090f76a 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -979,6 +979,16 @@ static int open_input_file(OptionsContext *o, const char *filename)
         av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
     }
 
+    if (o->stop_time_eof != AV_NOPTS_VALUE && o->recording_time != INT64_MAX) {
+        o->stop_time_eof = AV_NOPTS_VALUE;
+        av_log(NULL, AV_LOG_WARNING, "-t and -toeof cannot be used together; using -t.\n");
+    }
+
+    if (o->stop_time != INT64_MAX && o->stop_time_eof != AV_NOPTS_VALUE) {
+        o->stop_time_eof = AV_NOPTS_VALUE;
+        av_log(NULL, AV_LOG_WARNING, "-to and -toeof cannot be used together; using -to.\n");
+    }
+
     if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
         int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
         if (o->stop_time <= start_time) {
@@ -1109,6 +1119,21 @@ static int open_input_file(OptionsContext *o, const char *filename)
         } else
             av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
     }
+
+    if (o->stop_time_eof != AV_NOPTS_VALUE) {
+        if (o->start_time_eof != AV_NOPTS_VALUE && o->start_time_eof >= o->stop_time_eof) {
+            av_log(NULL, AV_LOG_FATAL, "-sseof value greater than -toeof; aborting.\n");
+            exit_program(1);
+        }
+        if (ic->duration>0) {
+            o->recording_time = ic->duration + o->stop_time_eof;
+
+            if (o->start_time != AV_NOPTS_VALUE) {
+                o->recording_time -= o->start_time;
+            }
+        } else
+            av_log(NULL, AV_LOG_WARNING, "Cannot use -toeof, duration of %s not known\n", filename);
+    }
     timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
     /* add the stream start time */
     if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
@@ -3334,6 +3359,8 @@ const OptionDef options[] = {
         "duration" },
     { "to",             HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,  { .off = OFFSET(stop_time) },
         "record or transcode stop time", "time_stop" },
+    { "toeof",          HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_INPUT, { .off = OFFSET(stop_time_eof) },
+        "input stop time relative to EOF", "time_stop" },
     { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
         "set the limit file size in bytes", "limit_size" },
     { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
-- 
2.17.1

