mirror of https://git.ffmpeg.org/ffmpeg.git
lavf/segment: add new option segment_clocktime_wrap_duration
This option can force the segmenter to only start a new segment if a packet reaches the muxer within 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. Reviewed-by: Stefano Sabatini <stefasab@gmail.com> Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
1036a1b8a3
commit
369a6a6ed4
|
@ -1110,6 +1110,18 @@ create files at 12:05, 12:20, 12:35, etc.
|
||||||
|
|
||||||
Default value is "0".
|
Default value is "0".
|
||||||
|
|
||||||
|
@item segment_clocktime_wrap_duration @var{duration}
|
||||||
|
Force the segmenter to only start a new segment if a packet reaches the muxer
|
||||||
|
within 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}
|
@item segment_time_delta @var{delta}
|
||||||
Specify the accuracy time when selecting the start time for a
|
Specify the accuracy time when selecting the start time for a
|
||||||
segment, expressed as a duration specification. Default value is "0".
|
segment, expressed as a duration specification. Default value is "0".
|
||||||
|
|
|
@ -83,6 +83,7 @@ typedef struct SegmentContext {
|
||||||
|
|
||||||
int use_clocktime; ///< flag to cut segments at regular clock time
|
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_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_val; ///< remember last time for wrap around detection
|
||||||
int64_t last_cut; ///< remember last cut
|
int64_t last_cut; ///< remember last cut
|
||||||
int cut_pending;
|
int cut_pending;
|
||||||
|
@ -784,7 +785,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
localtime_r(&sec, &ti);
|
localtime_r(&sec, &ti);
|
||||||
usecs = (int64_t)(ti.tm_hour * 3600 + ti.tm_min * 60 + ti.tm_sec) * 1000000 + (avgt % 1000000);
|
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;
|
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->cut_pending = 1;
|
||||||
seg->last_cut = usecs;
|
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_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, 86400000000LL, E},
|
{ "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
|
||||||
|
{ "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
|
||||||
{ "segment_time", "set segment duration", OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, 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_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 },
|
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
|
||||||
|
|
Loading…
Reference in New Issue