Commit 0c1759ac authored by Luca Barbato's avatar Luca Barbato

segment: implement wrap around

Provide a way to wrap around the segment index so pseudostreaming
live through a web server and html5 browser is simpler.

Also ensure that 0 (disable) is a valid value across the options
providing wrap around.
parent ee42df8a
...@@ -353,6 +353,8 @@ Set segment duration to @var{t} seconds. ...@@ -353,6 +353,8 @@ Set segment duration to @var{t} seconds.
Generate also a listfile named @var{name}. Generate also a listfile named @var{name}.
@item segment_list_size @var{size} @item segment_list_size @var{size}
Overwrite the listfile once it reaches @var{size} entries. Overwrite the listfile once it reaches @var{size} entries.
@item segment_wrap @var{limit}
Wrap around segment index once it reaches @var{limit}.
@end table @end table
@example @example
......
...@@ -39,6 +39,7 @@ typedef struct { ...@@ -39,6 +39,7 @@ typedef struct {
char *list; /**< Set by a private option. */ char *list; /**< Set by a private option. */
float time; /**< Set by a private option. */ float time; /**< Set by a private option. */
int size; /**< Set by a private option. */ int size; /**< Set by a private option. */
int wrap; /**< Set by a private option. */
int64_t offset_time; int64_t offset_time;
int64_t recording_time; int64_t recording_time;
int has_video; int has_video;
...@@ -51,6 +52,9 @@ static int segment_start(AVFormatContext *s) ...@@ -51,6 +52,9 @@ static int segment_start(AVFormatContext *s)
AVFormatContext *oc = c->avf; AVFormatContext *oc = c->avf;
int err = 0; int err = 0;
if (c->wrap)
c->number %= c->wrap;
if (av_get_frame_filename(oc->filename, sizeof(oc->filename), if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
s->filename, c->number++) < 0) s->filename, c->number++) < 0)
return AVERROR(EINVAL); return AVERROR(EINVAL);
...@@ -206,12 +210,11 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -206,12 +210,11 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
if (seg->list) { if (seg->list) {
avio_printf(seg->pb, "%s\n", oc->filename); avio_printf(seg->pb, "%s\n", oc->filename);
avio_flush(seg->pb); avio_flush(seg->pb);
if (!(seg->number % seg->size)) { if (seg->size && !(seg->number % seg->size)) {
avio_close(seg->pb); avio_close(seg->pb);
if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE, if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL)) < 0) &s->interrupt_callback, NULL)) < 0)
goto fail; goto fail;
} }
} }
} }
...@@ -250,6 +253,7 @@ static const AVOption options[] = { ...@@ -250,6 +253,7 @@ static const AVOption options[] = {
{ "segment_time", "segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E }, { "segment_time", "segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E },
{ "segment_list", "output the segment list", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_list", "output the segment list", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
{ "segment_list_size", "maximum number of playlist entries", OFFSET(size), AV_OPT_TYPE_INT, {.dbl = 5}, 0, INT_MAX, E }, { "segment_list_size", "maximum number of playlist entries", OFFSET(size), AV_OPT_TYPE_INT, {.dbl = 5}, 0, INT_MAX, E },
{ "segment_wrap", "number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, E },
{ NULL }, { NULL },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment