diff --git a/doc/muxers.texi b/doc/muxers.texi index dabf8b0929..2d7c32f482 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -450,6 +450,30 @@ listfile is generated. @item segment_list_size @var{size} Overwrite the listfile once it reaches @var{size} entries. If 0 the listfile is never overwritten. Default value is 5. +@item segment_list type @var{type} +Specify the format for the segment list file. + +The following values are recognized: +@table @option +@item flat +Generate a flat list for the created segments, one segment per line. + +@item ext +Generate a list for the created segments, one segment per line, +each line matching the format: +@example +@var{segment_filename},@var{segment_start_time},@var{segment_end_time} +@end example + +@var{segment_filename} is the name of the output file generated by the +muxer according to the provided pattern, and should not contain the +"," character for simplifying parsing operations. + +@var{segment_start_time} and @var{segment_end_time} specify +the segment start and end time expressed in seconds. +@end table + +Default value is "flat". @item segment_wrap @var{limit} Wrap around segment index once it reaches @var{limit}. @end table diff --git a/libavformat/segment.c b/libavformat/segment.c index e83ae9671b..f3a404d04a 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -30,6 +30,12 @@ #include "libavutil/parseutils.h" #include "libavutil/mathematics.h" +typedef enum { + LIST_TYPE_FLAT = 0, + LIST_TYPE_EXT, + LIST_TYPE_NB, +} ListType; + typedef struct { const AVClass *class; /**< Class for private options. */ int number; @@ -37,11 +43,13 @@ typedef struct { char *format; ///< format to use for output segment files char *list; ///< filename for the segment list file int list_size; ///< number of entries for the segment list file + ListType list_type; ///< set the list type AVIOContext *list_pb; ///< list file put-byte context float time; ///< segment duration int wrap; ///< number after which the index wraps int64_t recording_time; int has_video; + double start_time, end_time; } SegmentContext; static int segment_start(AVFormatContext *s) @@ -110,7 +118,12 @@ static int segment_end(AVFormatContext *s) &s->interrupt_callback, NULL)) < 0) goto end; } - avio_printf(seg->list_pb, "%s\n", oc->filename); + + if (seg->list_type == LIST_TYPE_FLAT) { + avio_printf(seg->list_pb, "%s\n", oc->filename); + } else if (seg->list_type == LIST_TYPE_EXT) { + avio_printf(seg->list_pb, "%s,%f,%f\n", oc->filename, seg->start_time, seg->end_time); + } avio_flush(seg->list_pb); } @@ -216,6 +229,10 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) if ((ret = segment_end(s)) < 0 || (ret = segment_start(s)) < 0) goto fail; + seg->start_time = (double)pkt->pts * av_q2d(st->time_base); + } else if (pkt->pts != AV_NOPTS_VALUE) { + seg->end_time = FFMAX(seg->end_time, + (double)(pkt->pts + pkt->duration) * av_q2d(st->time_base)); } ret = oc->oformat->write_packet(oc, pkt); @@ -252,6 +269,9 @@ static const AVOption options[] = { { "segment_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E }, { "segment_list", "set the segment list filename", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT, {.dbl = 5}, 0, INT_MAX, E }, + { "segment_list_type", "set the segment list type", OFFSET(list_type), AV_OPT_TYPE_INT, {.dbl = LIST_TYPE_FLAT}, 0, LIST_TYPE_NB-1, E, "list_type" }, + { "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.dbl=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, 0, "list_type" }, + { "ext", "extended format", 0, AV_OPT_TYPE_CONST, {.dbl=LIST_TYPE_EXT }, INT_MIN, INT_MAX, 0, "list_type" }, { "segment_wrap", "set number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, E }, { NULL }, }; diff --git a/libavformat/version.h b/libavformat/version.h index acf591aac6..43747ea750 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 15 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \