From: Michael Niedermayer <[email protected]>

This is the same logic as is invoked on AVFMT_TS_NEGATIVE,
but which can be enabled/disabled manually, or can be enabled
in muxers which only need it in certain conditions.

Also allow using the same mechanis to force streams to start
at 0.

This includes documentation by Stefano Sabatini, Clément Bœsch
and Michael Niedermayer.
---
 doc/muxers.texi             | 26 ++++++++++++++++++++++++++
 libavformat/avformat.h      | 18 +++++++++++++++++-
 libavformat/mux.c           | 12 ++++++++++--
 libavformat/options_table.h |  5 +++++
 libavformat/version.h       |  2 +-
 5 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 6d2c495..ede7786 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -16,6 +16,32 @@ with the options @code{--enable-muxer=@var{MUXER}} /
 The option @code{-formats} of the av* tools will display the list of
 enabled muxers.
 
+Some of the generic, muxer independent options are:
+
+@table @option
+@item avoid_negative_ts @var{integer} (@emph{output})
+
+Possible values:
+@table @samp
+@item make_non_negative
+Shift timestamps to make them non-negative.
+Also note that this affects only leading negative timestamps, and not
+non-monotonic negative timestamps.
+@item make_zero
+Shift timestamps so that the first timestamp is 0.
+@item auto (default)
+Enables shifting when required by the target format.
+@item disabled
+Disables shifting of timestamp.
+@end table
+
+When shifting is enabled, all output timestamps are shifted by the
+same amount. Audio, video, and subtitles desynching and relative
+timestamp differences are preserved compared to how they would have
+been without shifting.
+@end table
+
+
 A description of some of the currently available muxers follows.
 
 @anchor{crc}
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index f28186f..172e59e 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -429,7 +429,10 @@ typedef struct AVProbeData {
                                         timestamps. If not set the timestamp
                                         will be shifted in av_write_frame and
                                         av_interleaved_write_frame so they
-                                        start from 0. */
+                                        start from 0.
+                                        The user or muxer can override this 
through
+                                        AVFormatContext.avoid_negative_ts
+                                        */
 
 /**
  * @addtogroup lavf_encoding
@@ -1198,6 +1201,19 @@ typedef struct AVFormatContext {
      */
     int max_ts_probe;
 
+    /**
+     * Avoid negative timestamps during muxing.
+     * Any value of the AVFMT_AVOID_NEG_TS_* constants.
+     * Note, this only works when interleave_packet_per_dts is in use.
+     * - muxing: Set by user
+     * - demuxing: unused
+     */
+    int avoid_negative_ts;
+#define AVFMT_AVOID_NEG_TS_AUTO             -1 ///< Enabled when required by 
target format
+#define AVFMT_AVOID_NEG_TS_DISABLED          0 ///< Do not change timestamps
+#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they 
are non negative
+#define AVFMT_AVOID_NEG_TS_MAKE_ZERO         2 ///< Shift timestamps so that 
they start at 0
+
     /*****************************************************************
      * All fields below this line are not part of the public API. They
      * may not be used outside of libavformat and can be changed and
diff --git a/libavformat/mux.c b/libavformat/mux.c
index e4ba209..94b4391 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -248,6 +248,13 @@ int avformat_write_header(AVFormatContext *s, AVDictionary 
**options)
             return ret;
     }
 
+    if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO) {
+        if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
+            s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_DISABLED;
+        } else
+            s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
+    }
+
     return 0;
 }
 
@@ -318,11 +325,12 @@ static int compute_pkt_fields2(AVFormatContext *s, 
AVStream *st, AVPacket *pkt)
 static int write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret;
-    if (!(s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS))) {
+    if (s->avoid_negative_ts > 0) {
         AVRational time_base = s->streams[pkt->stream_index]->time_base;
         int64_t offset = 0;
 
-        if (!s->offset && pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
+        if (!s->offset && pkt->dts != AV_NOPTS_VALUE &&
+            (pkt->dts < 0 || s->avoid_negative_ts == 
AVFMT_AVOID_NEG_TS_MAKE_ZERO)) {
             s->offset = -pkt->dts;
             s->offset_timebase = time_base;
         }
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 0f7207c..ab60077 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -66,6 +66,11 @@ static const AVOption avformat_options[] = {
 {"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, 
INT_MIN, INT_MAX, D|E, "strict"},
 {"experimental", "allow non-standardized experimental variants", 0, 
AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, D|E, 
"strict"},
 {"max_ts_probe", "maximum number of packets to read while waiting for the 
first timestamp", OFFSET(max_ts_probe), AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 
INT_MAX, D },
+{"avoid_negative_ts", "shift timestamps so they start at 0", 
OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, E, 
"avoid_negative_ts"},
+{"auto",              "enabled when required by target format",    0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_AUTO },              INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
+{"disabled",          "do not change timestamps",                  0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_DISABLED },          INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
+{"make_non_negative", "shift timestamps so they are non negative", 0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE }, INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
+{"make_zero",         "shift timestamps so they start at 0",       0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_ZERO },         INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
 {NULL},
 };
 
diff --git a/libavformat/version.h b/libavformat/version.h
index dfb6089..c477d5d 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
 
 #define LIBAVFORMAT_VERSION_MAJOR 56
 #define LIBAVFORMAT_VERSION_MINOR  6
-#define LIBAVFORMAT_VERSION_MICRO  2
+#define LIBAVFORMAT_VERSION_MICRO  3
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
-- 
1.9.3 (Apple Git-50)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to