Signed-off-by: Christian Suloway
---
libavformat/hlsenc.c | 87 +---
1 file changed, 69 insertions(+), 18 deletions(-)
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index e13f438..0a48919 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -33,7 +33,7 @@
#include "internal.h"
typedef struct HLSSegment {
-char filename[1024];
+char *filename;
double duration; /* in seconds */
int64_t pos;
int64_t size;
@@ -73,14 +73,23 @@ typedef struct HLSContext {
HLSSegment *segments;
HLSSegment *last_segment;
+char *dirname;
char *basename;
char *baseurl;
char *format_options_str;
AVDictionary *format_options;
+char *segment_filename;
+
AVIOContext *pb;
} HLSContext;
+static void hls_free_segment(HLSSegment *en)
+{
+av_freep(&en->filename);
+av_freep(&en);
+}
+
static int hls_mux_init(AVFormatContext *s)
{
HLSContext *hls = s->priv_data;
@@ -119,7 +128,9 @@ static int hls_append_segment(HLSContext *hls, double
duration, int64_t pos,
if (!en)
return AVERROR(ENOMEM);
-av_strlcpy(en->filename, av_basename(hls->avf->filename),
sizeof(en->filename));
+en->filename = av_strdup(hls->avf->filename);
+if (!en->filename)
+return AVERROR(ENOMEM);
en->duration = duration;
en->pos = pos;
@@ -136,7 +147,7 @@ static int hls_append_segment(HLSContext *hls, double
duration, int64_t pos,
if (hls->max_nb_segments && hls->nb_entries >= hls->max_nb_segments) {
en = hls->segments;
hls->segments = en->next;
-av_free(en);
+hls_free_segment(en);
} else
hls->nb_entries++;
@@ -152,7 +163,7 @@ static void hls_free_segments(HLSContext *hls)
while(p) {
en = p;
p = p->next;
-av_free(en);
+hls_free_segment(en);
}
}
@@ -186,6 +197,7 @@ static int hls_window(AVFormatContext *s, int last)
sequence);
for (en = hls->segments; en; en = en->next) {
+
avio_printf(hls->pb, "#EXTINF:%f,\n", en->duration);
if (hls->flags & HLS_SINGLE_FILE)
avio_printf(hls->pb, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n",
@@ -208,6 +220,8 @@ static int hls_start(AVFormatContext *s)
HLSContext *c = s->priv_data;
AVFormatContext *oc = c->avf;
int err = 0;
+int filename_size;
+char *filename;
if (c->flags & HLS_SINGLE_FILE)
av_strlcpy(oc->filename, c->basename,
@@ -220,8 +234,18 @@ static int hls_start(AVFormatContext *s)
}
c->number++;
-if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
+filename_size = strlen(c->dirname) + strlen(oc->filename) + 1;
+filename = av_malloc(filename_size);
+if (!filename)
+return AVERROR(ENOMEM);
+*filename = '\0';
+av_strlcat(filename, c->dirname, filename_size);
+av_strlcat(filename, oc->filename, filename_size);
+
+err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL);
+av_free(filename);
+if (err < 0)
return err;
if (oc->oformat->priv_class && oc->priv_data)
@@ -237,15 +261,13 @@ static int hls_write_header(AVFormatContext *s)
char *p;
const char *pattern = "%d.ts";
AVDictionary *options = NULL;
-int basename_size = strlen(s->filename) + strlen(pattern) + 1;
+int basename_size;
+char *basename;
hls->sequence = hls->start_sequence;
hls->recording_time = hls->time * AV_TIME_BASE;
hls->start_pts = AV_NOPTS_VALUE;
-if (hls->flags & HLS_SINGLE_FILE)
-pattern = ".ts";
-
if (hls->format_options_str) {
ret = av_dict_parse_string(&hls->format_options,
hls->format_options_str, "=", ":", 0);
if (ret < 0) {
@@ -270,21 +292,45 @@ static int hls_write_header(AVFormatContext *s)
goto fail;
}
-hls->basename = av_malloc(basename_size);
-
-if (!hls->basename) {
+hls->dirname = av_strdup(s->filename);
+if (!hls->dirname) {
ret = AVERROR(ENOMEM);
goto fail;
}
-strcpy(hls->basename, s->filename);
+basename = (char *)av_basename(hls->dirname);
-p = strrchr(hls->basename, '.');
+if (hls->segment_filename) {
+hls->basename = av_strdup(av_basename(hls->segment_filename));
+if (!hls->basename) {
+ret = AVERROR(ENOMEM);
+goto fail;
+}
+if (strlen(hls->basename) != strlen(hls->segment_filename)) {
+av_log(hls, AV_LOG_ERROR, "invalid segment filename %s\n",
+ hls->segment_filename);
+ret = AVERROR(EINVAL);
+goto fail;
+}
+} else {
+if (hls->flags & HLS_SINGLE_FILE)
+pattern = ".ts";
-if (p)
-*p = '\0';
+basename_size = strlen(b