Commit 1384df64 authored by Michael Niedermayer's avatar Michael Niedermayer Committed by Martin Storsjö

lavf: Add an option for avoiding negative timestamps

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

Also allow using the same mechanism to force streams to start
at 0.
Signed-off-by: 's avatarMartin Storsjö <martin@martin.st>
parent 4981baf9
...@@ -13,6 +13,9 @@ libavutil: 2014-08-09 ...@@ -13,6 +13,9 @@ libavutil: 2014-08-09
API changes, most recent first: API changes, most recent first:
2014-11-xx - xxxxxxx - lavf 56.06.3 - avformat.h
Add AVFormatContext.avoid_negative_ts.
2014-11-xx - xxxxxxx - lavc 56.6.0 - vorbis_parser.h 2014-11-xx - xxxxxxx - lavc 56.6.0 - vorbis_parser.h
Add a public API for parsing vorbis packets. Add a public API for parsing vorbis packets.
......
...@@ -1198,6 +1198,18 @@ typedef struct AVFormatContext { ...@@ -1198,6 +1198,18 @@ typedef struct AVFormatContext {
*/ */
int max_ts_probe; int max_ts_probe;
/**
* Avoid negative timestamps during muxing.
* Any value of the AVFMT_AVOID_NEG_TS_* constants.
* Note, this only works when using av_interleaved_write_frame.
* - 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_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 * 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 * may not be used outside of libavformat and can be changed and
......
...@@ -248,6 +248,13 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) ...@@ -248,6 +248,13 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
return ret; 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 = 0;
} else
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
}
return 0; return 0;
} }
...@@ -318,11 +325,12 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) ...@@ -318,11 +325,12 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
static int write_packet(AVFormatContext *s, AVPacket *pkt) static int write_packet(AVFormatContext *s, AVPacket *pkt)
{ {
int ret; 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; AVRational time_base = s->streams[pkt->stream_index]->time_base;
int64_t offset = 0; 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 = -pkt->dts;
s->offset_timebase = time_base; s->offset_timebase = time_base;
} }
......
...@@ -66,6 +66,10 @@ static const AVOption avformat_options[] = { ...@@ -66,6 +66,10 @@ static const AVOption avformat_options[] = {
{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, D|E, "strict"}, {"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"}, {"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 }, {"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"},
{"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}, {NULL},
}; };
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 56 #define LIBAVFORMAT_VERSION_MAJOR 56
#define LIBAVFORMAT_VERSION_MINOR 6 #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, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment