double start_time, end_time;
int64_t start_pts;
int64_t offset_pts;
- char filename[1024];
+ char *filename;
struct SegmentListEntry *next;
} SegmentListEntry;
char *list; ///< filename for the segment list file
int list_flags; ///< flags affecting list generation
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
AVIOContext *list_pb; ///< list file put-byte context
char *time_str; ///< segment duration specification string
{
SegmentContext *seg = s->priv_data;
AVFormatContext *oc = seg->avf;
+ size_t size;
if (seg->segment_idx_wrap)
seg->segment_idx %= seg->segment_idx_wrap;
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
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 err;
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
+ &s->interrupt_callback, NULL)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename);
return err;
+ }
if (oc->oformat->priv_class && oc->priv_data)
av_opt_set(oc->priv_data, "resend_headers", "1", 0); /* mpegts specific */
ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list);
return ret;
+ }
if (seg->list_type == LIST_TYPE_M3U8 && seg->segment_list_entries) {
SegmentListEntry *entry;
if (seg->list_size && seg->segment_count > seg->list_size) {
entry = seg->segment_list_entries;
seg->segment_list_entries = seg->segment_list_entries->next;
+ av_free(entry->filename);
av_freep(&entry);
}
if (seg->write_header_trailer) {
if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
+ &s->interrupt_callback, NULL)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename);
goto fail;
+ }
} else {
if ((ret = open_null_ctx(&oc->pb)) < 0)
goto fail;
cur = seg->segment_list_entries;
while (cur) {
next = cur->next;
+ av_free(cur->filename);
av_free(cur);
cur = next;
}
{ "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_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" },
{ "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" },