Commit 5e278c19 authored by Stefano Sabatini's avatar Stefano Sabatini

lavf/segment: add segment_list_entry_prefix option

This option allows to add a prefix to the segment list entry filenames.

Also set by default the list entry filenames to the corresponding
segment basename, consistent with the HLS muxer.

Based on an idea by Steven Liu <lingjiujianke@gmail.com>.
parent 7f11c530
...@@ -674,7 +674,9 @@ The segment muxer works best with a single constant frame rate video. ...@@ -674,7 +674,9 @@ The segment muxer works best with a single constant frame rate video.
Optionally it can generate a list of the created segments, by setting Optionally it can generate a list of the created segments, by setting
the option @var{segment_list}. The list type is specified by the the option @var{segment_list}. The list type is specified by the
@var{segment_list_type} option. @var{segment_list_type} option. The entry filenames in the segment
list are set by default to the basename of the corresponding segment
files.
The segment muxer supports the following options: The segment muxer supports the following options:
...@@ -711,6 +713,10 @@ Update the list file so that it contains at most the last @var{size} ...@@ -711,6 +713,10 @@ Update the list file so that it contains at most the last @var{size}
segments. If 0 the list file will contain all the segments. Default segments. If 0 the list file will contain all the segments. Default
value is 0. value is 0.
@item segment_list_entry_prefix @var{prefix}
Set @var{prefix} to prepend to the name of each entry filename. By
default no prefix is applied.
@item segment_list_type @var{type} @item segment_list_type @var{type}
Specify the format for the segment list file. Specify the format for the segment list file.
......
...@@ -44,7 +44,7 @@ typedef struct SegmentListEntry { ...@@ -44,7 +44,7 @@ typedef struct SegmentListEntry {
double start_time, end_time; double start_time, end_time;
int64_t start_pts; int64_t start_pts;
int64_t offset_pts; int64_t offset_pts;
char filename[1024]; char *filename;
struct SegmentListEntry *next; struct SegmentListEntry *next;
} SegmentListEntry; } SegmentListEntry;
...@@ -72,6 +72,7 @@ typedef struct { ...@@ -72,6 +72,7 @@ typedef struct {
char *list; ///< filename for the segment list file char *list; ///< filename for the segment list file
int list_flags; ///< flags affecting list generation int list_flags; ///< flags affecting list generation
int list_size; ///< number of entries for the segment list file int list_size; ///< number of entries for the segment list file
char *list_entry_prefix; ///< prefix to add to list entry filenames
ListType list_type; ///< set the list type ListType list_type; ///< set the list type
AVIOContext *list_pb; ///< list file put-byte context AVIOContext *list_pb; ///< list file put-byte context
char *time_str; ///< segment duration specification string char *time_str; ///< segment duration specification string
...@@ -158,6 +159,7 @@ static int set_segment_filename(AVFormatContext *s) ...@@ -158,6 +159,7 @@ static int set_segment_filename(AVFormatContext *s)
{ {
SegmentContext *seg = s->priv_data; SegmentContext *seg = s->priv_data;
AVFormatContext *oc = seg->avf; AVFormatContext *oc = seg->avf;
size_t size;
if (seg->segment_idx_wrap) if (seg->segment_idx_wrap)
seg->segment_idx %= seg->segment_idx_wrap; seg->segment_idx %= seg->segment_idx_wrap;
...@@ -166,7 +168,19 @@ static int set_segment_filename(AVFormatContext *s) ...@@ -166,7 +168,19 @@ static int set_segment_filename(AVFormatContext *s)
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename); av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
av_strlcpy(seg->cur_entry.filename, oc->filename, sizeof(seg->cur_entry.filename));
/* copy modified name in list entry */
size = strlen(av_basename(oc->filename)) + 1;
if (seg->list_entry_prefix)
size += strlen(seg->list_entry_prefix);
seg->cur_entry.filename = av_mallocz(size);
if (!seg->cur_entry.filename)
return AVERROR(ENOMEM);
snprintf(seg->cur_entry.filename, size, "%s%s",
seg->list_entry_prefix ? seg->list_entry_prefix : "",
av_basename(oc->filename));
return 0; return 0;
} }
...@@ -303,6 +317,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) ...@@ -303,6 +317,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
if (seg->list_size && seg->segment_count > seg->list_size) { if (seg->list_size && seg->segment_count > seg->list_size) {
entry = seg->segment_list_entries; entry = seg->segment_list_entries;
seg->segment_list_entries = seg->segment_list_entries->next; seg->segment_list_entries = seg->segment_list_entries->next;
av_free(entry->filename);
av_freep(&entry); av_freep(&entry);
} }
...@@ -746,6 +761,7 @@ fail: ...@@ -746,6 +761,7 @@ fail:
cur = seg->segment_list_entries; cur = seg->segment_list_entries;
while (cur) { while (cur) {
next = cur->next; next = cur->next;
av_free(cur->filename);
av_free(cur); av_free(cur);
cur = next; cur = next;
} }
...@@ -766,6 +782,7 @@ static const AVOption options[] = { ...@@ -766,6 +782,7 @@ static const AVOption options[] = {
{ "live", "enable live-friendly list generation (useful for HLS)", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_LIVE }, INT_MIN, INT_MAX, E, "list_flags"}, { "live", "enable live-friendly list generation (useful for HLS)", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_LIVE }, INT_MIN, INT_MAX, E, "list_flags"},
{ "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, { "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
{ "segment_list_entry_prefix", "set prefix to prepend to each list entry filename", OFFSET(list_entry_prefix), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
{ "segment_list_type", "set the segment list type", OFFSET(list_type), AV_OPT_TYPE_INT, {.i64 = LIST_TYPE_UNDEFINED}, -1, LIST_TYPE_NB-1, E, "list_type" }, { "segment_list_type", "set the segment list type", OFFSET(list_type), AV_OPT_TYPE_INT, {.i64 = LIST_TYPE_UNDEFINED}, -1, LIST_TYPE_NB-1, E, "list_type" },
{ "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" }, { "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" },
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 55 #define LIBAVFORMAT_VERSION_MAJOR 55
#define LIBAVFORMAT_VERSION_MINOR 21 #define LIBAVFORMAT_VERSION_MINOR 21
#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \
......
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