This allows avoiding negative timestamps.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -832,6 +832,13 @@ typedef struct AVStream { |
832 | 832 |
* its lifetime differs from info which is why its not in that structure. |
833 | 833 |
*/ |
834 | 834 |
int nb_decoded_frames; |
835 |
+ |
|
836 |
+ /** |
|
837 |
+ * Timestamp offset added to timestamps before muxing |
|
838 |
+ * NOT PART OF PUBLIC API |
|
839 |
+ */ |
|
840 |
+ int64_t mux_ts_offset; |
|
841 |
+ |
|
835 | 842 |
} AVStream; |
836 | 843 |
|
837 | 844 |
#define AV_PROGRAM_RUNNING 1 |
... | ... |
@@ -1111,6 +1118,17 @@ typedef struct AVFormatContext { |
1111 | 1111 |
*/ |
1112 | 1112 |
int use_wallclock_as_timestamps; |
1113 | 1113 |
|
1114 |
+ /** |
|
1115 |
+ * Avoids negative timestamps during muxing |
|
1116 |
+ * 0 -> allow negative timestamps |
|
1117 |
+ * 1 -> avoid negative timestamps |
|
1118 |
+ * -1 -> choose automatically (default) |
|
1119 |
+ * Note, this is only works when interleave_packet_per_dts is in use |
|
1120 |
+ * - encoding: Set by user via AVOptions (NO direct access) |
|
1121 |
+ * - decoding: unused |
|
1122 |
+ */ |
|
1123 |
+ int avoid_negative_ts; |
|
1124 |
+ |
|
1114 | 1125 |
/***************************************************************** |
1115 | 1126 |
* All fields below this line are not part of the public API. They |
1116 | 1127 |
* may not be used outside of libavformat and can be changed and |
... | ... |
@@ -71,6 +71,7 @@ static const AVOption options[]={ |
71 | 71 |
{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"}, |
72 | 72 |
{"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"}, |
73 | 73 |
{"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D}, |
74 |
+{"avoid_negative_ts", "avoid negative timestamps", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E}, |
|
74 | 75 |
{NULL}, |
75 | 76 |
}; |
76 | 77 |
|
... | ... |
@@ -3699,16 +3699,36 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, |
3699 | 3699 |
} |
3700 | 3700 |
} |
3701 | 3701 |
if(stream_count && flush){ |
3702 |
+ AVStream *st; |
|
3702 | 3703 |
pktl= s->packet_buffer; |
3703 | 3704 |
*out= pktl->pkt; |
3705 |
+ st = s->streams[out->stream_index]; |
|
3704 | 3706 |
|
3705 | 3707 |
s->packet_buffer= pktl->next; |
3706 | 3708 |
if(!s->packet_buffer) |
3707 | 3709 |
s->packet_buffer_end= NULL; |
3708 | 3710 |
|
3709 |
- if(s->streams[out->stream_index]->last_in_packet_buffer == pktl) |
|
3710 |
- s->streams[out->stream_index]->last_in_packet_buffer= NULL; |
|
3711 |
+ if(st->last_in_packet_buffer == pktl) |
|
3712 |
+ st->last_in_packet_buffer= NULL; |
|
3711 | 3713 |
av_freep(&pktl); |
3714 |
+ |
|
3715 |
+ if (s->avoid_negative_ts > 0) { |
|
3716 |
+ if (out->dts != AV_NOPTS_VALUE) { |
|
3717 |
+ if (!st->mux_ts_offset && out->dts < 0) { |
|
3718 |
+ for(i=0; i < s->nb_streams; i++) { |
|
3719 |
+ s->streams[i]->mux_ts_offset = |
|
3720 |
+ av_rescale_q_rnd(-out->dts, |
|
3721 |
+ st->time_base, |
|
3722 |
+ s->streams[i]->time_base, |
|
3723 |
+ AV_ROUND_UP); |
|
3724 |
+ } |
|
3725 |
+ } |
|
3726 |
+ out->dts += st->mux_ts_offset; |
|
3727 |
+ } |
|
3728 |
+ if (out->pts != AV_NOPTS_VALUE) |
|
3729 |
+ out->pts += st->mux_ts_offset; |
|
3730 |
+ } |
|
3731 |
+ |
|
3712 | 3732 |
return 1; |
3713 | 3733 |
}else{ |
3714 | 3734 |
av_init_packet(out); |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
#include "libavutil/avutil.h" |
31 | 31 |
|
32 | 32 |
#define LIBAVFORMAT_VERSION_MAJOR 54 |
33 |
-#define LIBAVFORMAT_VERSION_MINOR 28 |
|
33 |
+#define LIBAVFORMAT_VERSION_MINOR 29 |
|
34 | 34 |
#define LIBAVFORMAT_VERSION_MICRO 101 |
35 | 35 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |