lavf/segment: add segment_list_type option, extend format for the segment list file
Add list extended format which specifies in the list file the start and ending time for each segment. This is required to make it available this information to external tools, avoiding the need to perform file analysis in the output segments.
This commit is contained in:
parent
b010d9b586
commit
7f08bfae6e
3 changed files with 46 additions and 2 deletions
|
@ -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 },
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue