This option can force the segmenter to only start a new segment if a packet reaches the muxer whithin the specified duration after the segmenting clock time, which makes it more resilient to backward local time jumps, such as leap seconds or transition to standard time from daylight savings time.
Signed-off-by: Marton Balint <c...@passwd.hu> --- doc/muxers.texi | 13 +++++++++++++ libavformat/segment.c | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index c304221..2ed468e 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1110,6 +1110,19 @@ create files at 12:05, 12:20, 12:35, etc. Default value is "0". +@item segment_clocktime_wrap_duration @var{duration} +By setting this option you can force the segmenter to only start a new segment +if a packet reaches the muxer whithin the specified duration after the +segmenting clock time. This way you can make the segmenter more resilient to +backward local time jumps, such as leap seconds or transition to standard time +from daylight savings time. + +Assuming that the delay between the packets of your source is less than 0.5 +second you can detect a leap second by specifying 0.5 as the duration. + +Default is the maximum possible duration which means starting a new segment +regardless of the elapsed time since the last clock time. + @item segment_time_delta @var{delta} Specify the accuracy time when selecting the start time for a segment, expressed as a duration specification. Default value is "0". diff --git a/libavformat/segment.c b/libavformat/segment.c index bf7a8fc..d92b9c3 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -83,6 +83,7 @@ typedef struct SegmentContext { int use_clocktime; ///< flag to cut segments at regular clock time int64_t clocktime_offset; //< clock offset for cutting the segments at regular clock time + int64_t clocktime_wrap_duration; //< wrapping duration considered for starting a new segment int64_t last_val; ///< remember last time for wrap around detection int64_t last_cut; ///< remember last cut int cut_pending; @@ -784,7 +785,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) localtime_r(&sec, &ti); usecs = (int64_t)(ti.tm_hour * 3600 + ti.tm_min * 60 + ti.tm_sec) * 1000000 + (avgt % 1000000); wrapped_val = (usecs + seg->clocktime_offset) % seg->time; - if (seg->last_cut != usecs && wrapped_val < seg->last_val) { + if (seg->last_cut != usecs && wrapped_val < seg->last_val && wrapped_val < seg->clocktime_wrap_duration) { seg->cut_pending = 1; seg->last_cut = usecs; } @@ -935,6 +936,7 @@ static const AVOption options[] = { { "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E}, { "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400, E}, + { "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT_MAX}, 0, INT_MAX, E}, { "segment_time", "set segment duration", OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0, E }, { "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E }, -- 2.6.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel