summaryrefslogtreecommitdiffstats
path: root/libavformat/hlsenc.c
diff options
context:
space:
mode:
authorVishwanath Dixit <vdixit@akamai.com>2018-01-02 10:46:17 +0800
committerSteven Liu <lq@chinaffmpeg.org>2018-01-02 10:46:17 +0800
commite872befdb5974bb609e337c895cefbf9bb51187c (patch)
treea75ce5f194e7ff86681e047dc30b9783f6c14fbb /libavformat/hlsenc.c
parent26e1efb04f3864b813c74eaf85fbe1ea352bb7f0 (diff)
downloadffmpeg-streaming-e872befdb5974bb609e337c895cefbf9bb51187c.zip
ffmpeg-streaming-e872befdb5974bb609e337c895cefbf9bb51187c.tar.gz
avformat/hlsenc: configurable variant stream index position in filenames
Diffstat (limited to 'libavformat/hlsenc.c')
-rw-r--r--libavformat/hlsenc.c153
1 files changed, 101 insertions, 52 deletions
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 3ea16c6..e1dd606 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1528,7 +1528,7 @@ static const char * get_default_pattern_localtime_fmt(AVFormatContext *s)
return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts";
}
-static int format_name(char *name, int name_buf_len, int i)
+static int append_postfix(char *name, int name_buf_len, int i)
{
char *p;
char extension[10] = {'\0'};
@@ -1547,6 +1547,53 @@ static int format_name(char *name, int name_buf_len, int i)
return 0;
}
+static int validate_name(int nb_vs, const char *fn)
+{
+ const char *filename;
+ int ret = 0;
+
+ if (!fn) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ filename = av_basename(fn);
+
+ if (nb_vs > 1 && !av_stristr(filename, "%v")) {
+ av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected in the filename %s\n",
+ fn);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+fail:
+ return ret;
+}
+
+static int format_name(char *buf, int buf_len, int index)
+{
+ char *orig_buf_dup = NULL;
+ int ret = 0;
+
+ if (!av_stristr(buf, "%v"))
+ return ret;
+
+ orig_buf_dup = av_strdup(buf);
+ if (!orig_buf_dup) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (replace_int_data_in_filename(buf, buf_len, orig_buf_dup, 'v', index) < 1) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+fail:
+ av_freep(&orig_buf_dup);
+ return ret;
+}
+
static int get_nth_codec_stream_index(AVFormatContext *s,
enum AVMediaType codec_type,
int stream_id)
@@ -1690,7 +1737,7 @@ static int update_variant_stream_info(AVFormatContext *s) {
static int update_master_pl_info(AVFormatContext *s) {
HLSContext *hls = s->priv_data;
const char *dir;
- char *fn;
+ char *fn = NULL;
int ret = 0;
fn = av_strdup(s->filename);
@@ -2052,7 +2099,7 @@ static int hls_init(AVFormatContext *s)
const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
const char *vtt_pattern = "%d.vtt";
char *p = NULL;
- int vtt_basename_size = 0, m3u8_name_size = 0;
+ int vtt_basename_size = 0;
int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
ret = update_variant_stream_info(s);
@@ -2068,6 +2115,28 @@ static int hls_init(AVFormatContext *s)
goto fail;
}
+ ret = validate_name(hls->nb_varstreams, s->filename);
+ if (ret < 0)
+ goto fail;
+
+ if (hls->segment_filename) {
+ ret = validate_name(hls->nb_varstreams, hls->segment_filename);
+ if (ret < 0)
+ goto fail;
+ }
+
+ if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
+ ret = validate_name(hls->nb_varstreams, hls->fmp4_init_filename);
+ if (ret < 0)
+ goto fail;
+ }
+
+ if (hls->subtitle_filename) {
+ ret = validate_name(hls->nb_varstreams, hls->subtitle_filename);
+ if (ret < 0)
+ goto fail;
+ }
+
if (hls->master_pl_name) {
ret = update_master_pl_info(s);
if (ret < 0) {
@@ -2100,6 +2169,16 @@ static int hls_init(AVFormatContext *s)
hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
for (i = 0; i < hls->nb_varstreams; i++) {
vs = &hls->var_streams[i];
+
+ vs->m3u8_name = av_strdup(s->filename);
+ if (!vs->m3u8_name ) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ret = format_name(vs->m3u8_name, strlen(s->filename) + 1, i);
+ if (ret < 0)
+ goto fail;
+
vs->sequence = hls->start_sequence;
vs->start_pts = AV_NOPTS_VALUE;
vs->end_pts = AV_NOPTS_VALUE;
@@ -2153,9 +2232,6 @@ static int hls_init(AVFormatContext *s)
}
if (hls->segment_filename) {
basename_size = strlen(hls->segment_filename) + 1;
- if (hls->nb_varstreams > 1) {
- basename_size += strlen(POSTFIX_PATTERN);
- }
vs->basename = av_malloc(basename_size);
if (!vs->basename) {
ret = AVERROR(ENOMEM);
@@ -2163,6 +2239,9 @@ static int hls_init(AVFormatContext *s)
}
av_strlcpy(vs->basename, hls->segment_filename, basename_size);
+ ret = format_name(vs->basename, basename_size, i);
+ if (ret < 0)
+ goto fail;
} else {
if (hls->flags & HLS_SINGLE_FILE) {
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
@@ -2173,13 +2252,9 @@ static int hls_init(AVFormatContext *s)
}
if (hls->use_localtime) {
- basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1;
+ basename_size = strlen(vs->m3u8_name) + strlen(pattern_localtime_fmt) + 1;
} else {
- basename_size = strlen(s->filename) + strlen(pattern) + 1;
- }
-
- if (hls->nb_varstreams > 1) {
- basename_size += strlen(POSTFIX_PATTERN);
+ basename_size = strlen(vs->m3u8_name) + strlen(pattern) + 1;
}
vs->basename = av_malloc(basename_size);
@@ -2188,7 +2263,7 @@ static int hls_init(AVFormatContext *s)
goto fail;
}
- av_strlcpy(vs->basename, s->filename, basename_size);
+ av_strlcpy(vs->basename, vs->m3u8_name, basename_size);
p = strrchr(vs->basename, '.');
if (p)
@@ -2200,28 +2275,6 @@ static int hls_init(AVFormatContext *s)
}
}
- m3u8_name_size = strlen(s->filename) + 1;
- if (hls->nb_varstreams > 1) {
- m3u8_name_size += strlen(POSTFIX_PATTERN);
- }
-
- vs->m3u8_name = av_malloc(m3u8_name_size);
- if (!vs->m3u8_name ) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- av_strlcpy(vs->m3u8_name, s->filename, m3u8_name_size);
-
- if (hls->nb_varstreams > 1) {
- ret = format_name(vs->basename, basename_size, i);
- if (ret < 0)
- goto fail;
- ret = format_name(vs->m3u8_name, m3u8_name_size, i);
- if (ret < 0)
- goto fail;
- }
-
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
if (hls->nb_varstreams > 1)
fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
@@ -2232,13 +2285,12 @@ static int hls_init(AVFormatContext *s)
}
av_strlcpy(vs->fmp4_init_filename, hls->fmp4_init_filename,
fmp4_init_filename_len);
- if (hls->nb_varstreams > 1) {
+
+ if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
ret = format_name(vs->fmp4_init_filename, fmp4_init_filename_len, i);
if (ret < 0)
goto fail;
- }
- if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
fmp4_init_filename_len = strlen(vs->fmp4_init_filename) + 1;
vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
if (!vs->base_output_dirname) {
@@ -2248,6 +2300,12 @@ static int hls_init(AVFormatContext *s)
av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
fmp4_init_filename_len);
} else {
+ if (hls->nb_varstreams > 1) {
+ ret = append_postfix(vs->fmp4_init_filename, fmp4_init_filename_len, i);
+ if (ret < 0)
+ goto fail;
+ }
+
fmp4_init_filename_len = strlen(vs->m3u8_name) +
strlen(vs->fmp4_init_filename) + 1;
@@ -2286,10 +2344,7 @@ static int hls_init(AVFormatContext *s)
if (hls->flags & HLS_SINGLE_FILE)
vtt_pattern = ".vtt";
- vtt_basename_size = strlen(s->filename) + strlen(vtt_pattern) + 1;
- if (hls->nb_varstreams > 1) {
- vtt_basename_size += strlen(POSTFIX_PATTERN);
- }
+ vtt_basename_size = strlen(vs->m3u8_name) + strlen(vtt_pattern) + 1;
vs->vtt_basename = av_malloc(vtt_basename_size);
if (!vs->vtt_basename) {
@@ -2301,27 +2356,21 @@ static int hls_init(AVFormatContext *s)
ret = AVERROR(ENOMEM);
goto fail;
}
- av_strlcpy(vs->vtt_basename, s->filename, vtt_basename_size);
+ av_strlcpy(vs->vtt_basename, vs->m3u8_name, vtt_basename_size);
p = strrchr(vs->vtt_basename, '.');
if (p)
*p = '\0';
if ( hls->subtitle_filename ) {
strcpy(vs->vtt_m3u8_name, hls->subtitle_filename);
+ ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
+ if (ret < 0)
+ goto fail;
} else {
strcpy(vs->vtt_m3u8_name, vs->vtt_basename);
av_strlcat(vs->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
}
av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
-
- if (hls->nb_varstreams > 1) {
- ret= format_name(vs->vtt_basename, vtt_basename_size, i);
- if (ret < 0)
- goto fail;
- ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
- if (ret < 0)
- goto fail;
- }
}
if (hls->baseurl) {
OpenPOWER on IntegriCloud