Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Marton Balint <cus@passwd.hu>
... | ... |
@@ -1100,6 +1100,16 @@ to create files at 12:00 o'clock, 12:15, 12:30, etc. |
1100 | 1100 |
|
1101 | 1101 |
Default value is "0". |
1102 | 1102 |
|
1103 |
+@item segment_clocktime_offset @var{duration} |
|
1104 |
+Delay the segment splitting times with the specified duration when using |
|
1105 |
+@option{segment_atclocktime}. |
|
1106 |
+ |
|
1107 |
+For example with @option{segment_time} set to "900" and |
|
1108 |
+@option{segment_clocktime_offset} set to "300" this makes it possible to |
|
1109 |
+create files at 12:05, 12:20, 12:35, etc. |
|
1110 |
+ |
|
1111 |
+Default value is "0". |
|
1112 |
+ |
|
1103 | 1113 |
@item segment_time_delta @var{delta} |
1104 | 1114 |
Specify the accuracy time when selecting the start time for a |
1105 | 1115 |
segment, expressed as a duration specification. Default value is "0". |
... | ... |
@@ -82,6 +82,7 @@ typedef struct SegmentContext { |
82 | 82 |
int list_size; ///< number of entries for the segment list file |
83 | 83 |
|
84 | 84 |
int use_clocktime; ///< flag to cut segments at regular clock time |
85 |
+ int64_t clocktime_offset; //< clock offset for cutting the segments at regular clock time |
|
85 | 86 |
int64_t last_val; ///< remember last time for wrap around detection |
86 | 87 |
int64_t last_cut; ///< remember last cut |
87 | 88 |
int cut_pending; |
... | ... |
@@ -633,6 +634,13 @@ static int seg_write_header(AVFormatContext *s) |
633 | 633 |
seg->time_str); |
634 | 634 |
return ret; |
635 | 635 |
} |
636 |
+ if (seg->use_clocktime) { |
|
637 |
+ if (seg->time <= 0) { |
|
638 |
+ av_log(s, AV_LOG_ERROR, "Invalid negative segment_time with segment_atclocktime option set\n"); |
|
639 |
+ return AVERROR(EINVAL); |
|
640 |
+ } |
|
641 |
+ seg->clocktime_offset = seg->time - (seg->clocktime_offset % seg->time); |
|
642 |
+ } |
|
636 | 643 |
} |
637 | 644 |
|
638 | 645 |
if (seg->format_options_str) { |
... | ... |
@@ -775,7 +783,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) |
775 | 775 |
time_t sec = avgt / 1000000; |
776 | 776 |
localtime_r(&sec, &ti); |
777 | 777 |
usecs = (int64_t)(ti.tm_hour * 3600 + ti.tm_min * 60 + ti.tm_sec) * 1000000 + (avgt % 1000000); |
778 |
- wrapped_val = usecs % seg->time; |
|
778 |
+ wrapped_val = (usecs + seg->clocktime_offset) % seg->time; |
|
779 | 779 |
if (seg->last_cut != usecs && wrapped_val < seg->last_val) { |
780 | 780 |
seg->cut_pending = 1; |
781 | 781 |
seg->last_cut = usecs; |
... | ... |
@@ -926,6 +934,7 @@ static const AVOption options[] = { |
926 | 926 |
{ "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" }, |
927 | 927 |
|
928 | 928 |
{ "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E}, |
929 |
+ { "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E}, |
|
929 | 930 |
{ "segment_time", "set segment duration", OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, |
930 | 931 |
{ "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0, E }, |
931 | 932 |
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E }, |