65 #define SEGMENT_LIST_FLAG_CACHE 1
66 #define SEGMENT_LIST_FLAG_LIVE 2
120 int needs_quoting = !!str[strcspn(str,
"\",\n\r")];
125 for (; *str; str++) {
256 double max_duration = 0;
269 avio_printf(seg->
list_pb,
"#EXT-X-TARGETDURATION:%"PRId64
"\n", (int64_t)ceil(max_duration));
300 "Error writing list entry '%s' in list file\n", list_entry->
filename);
335 memcpy(entry, &seg->
cur_entry,
sizeof(*entry));
373 static int parse_times(
void *log_ctx, int64_t **times,
int *nb_times,
374 const char *times_str)
379 char *saveptr = NULL;
384 #define FAIL(err) ret = err; goto end
387 for (p = times_str1; *p; p++)
398 for (i = 0; i < *nb_times; i++) {
400 char *tstr =
av_strtok(p,
",", &saveptr);
403 if (!tstr || !tstr[0]) {
412 "Invalid time duration specification '%s' in times list %s\n", tstr, times_str);
418 if (i && (*times)[i-1] > (*times)[i]) {
420 "Specified time %f is greater than the following time %f\n",
421 (
float)((*times)[i])/1000000, (
float)((*times)[i-1])/1000000);
432 const char *frames_str)
436 char *frames_str1 =
av_strdup(frames_str);
437 char *saveptr = NULL;
442 #define FAIL(err) ret = err; goto end
445 for (p = frames_str1; *p; p++)
456 for (i = 0; i < *nb_frames; i++) {
459 char *fstr =
av_strtok(p,
",", &saveptr);
467 f = strtol(fstr, &tailptr, 10);
468 if (*tailptr || f <= 0 || f >= INT_MAX) {
470 "Invalid argument '%s', must be a positive integer <= INT64_MAX\n",
477 if (i && (*frames)[i-1] > (*frames)[i]) {
479 "Specified frame %d is greater than the following frame %d\n",
480 (*frames)[i], (*frames)[i-1]);
492 int buf_size = 32768;
519 static const enum AVMediaType type_priority_list[] = {
529 type_index_map[i] = -1;
534 if ((
unsigned)type < AVMEDIA_TYPE_NB && type_index_map[type] == -1
537 type_index_map[
type] = i;
541 type = type_priority_list[i];
581 "segment_time, segment_times, and segment_frames options "
582 "are mutually exclusive, select just one of them\n");
598 "Invalid time duration specification '%s' for segment_time option\n",
668 "Some of the provided format options in '%s' are not recognized\n", seg->
format_options_str);
711 int64_t end_pts = INT64_MAX,
offset;
712 int start_frame = INT_MAX;
727 time_t sec = avgt / 1000000;
729 usecs = (int64_t)(ti.tm_hour*3600 + ti.tm_min*60 + ti.tm_sec) * 1000000 + (avgt % 1000000);
730 wrapped_val = usecs % seg->
time;
731 if (seg->
last_cut != usecs && wrapped_val < seg->last_val) {
741 av_dlog(s,
"packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n",
777 av_log(s,
AV_LOG_VERBOSE,
"segment:'%s' starts with packet stream:%d pts:%s pts_time:%s frame:%d\n",
782 av_log(s,
AV_LOG_DEBUG,
"stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
848 #define OFFSET(x) offsetof(SegmentContext, x)
849 #define E AV_OPT_FLAG_ENCODING_PARAM
851 {
"reference_stream",
"set reference stream",
OFFSET(reference_stream_specifier),
AV_OPT_TYPE_STRING, {.str =
"auto"}, CHAR_MIN, CHAR_MAX,
E },
852 {
"segment_format",
"set container format used for the segments",
OFFSET(format),
AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0,
E },
853 {
"segment_format_options",
"set list of options for the container format used for the segments",
OFFSET(format_options_str),
AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0,
E },
860 {
"segment_list_size",
"set the maximum number of playlist entries",
OFFSET(list_size),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
E },
870 {
"segment_atclocktime",
"set segment to be cut at clocktime",
OFFSET(use_clocktime),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1,
E},
872 {
"segment_time_delta",
"set approximation value used for the segment times",
OFFSET(time_delta),
AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0,
E },
875 {
"segment_wrap",
"set number after which the index wraps",
OFFSET(segment_idx_wrap),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
E },
876 {
"segment_list_entry_prefix",
"set base url prefix for segments",
OFFSET(entry_prefix),
AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0,
E },
877 {
"segment_start_number",
"set the sequence number of the first segment",
OFFSET(segment_idx),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
E },
878 {
"segment_wrap_number",
"set the number of wrap before the first segment",
OFFSET(segment_idx_wrap_nb),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
E },
880 {
"individual_header_trailer",
"write header/trailer to each segment",
OFFSET(individual_header_trailer),
AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1,
E },
881 {
"write_header_trailer",
"write a header to the first segment and a trailer to the last one",
OFFSET(write_header_trailer),
AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1,
E },
882 {
"reset_timestamps",
"reset timestamps at the begin of each segment",
OFFSET(reset_timestamps),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1,
E },
883 {
"initial_offset",
"set initial timestamp offset",
OFFSET(initial_offset),
AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX,
E },
902 .priv_class = &seg_class,
913 .
name =
"stream_segment,ssegment",
920 .priv_class = &sseg_class,