From 0d2dd5d96d0dc8218192820dd4a34d5f7770148a Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 28 Sep 2016 16:09:05 +0800 Subject: [PATCH] avformat/hlsenc: support mkdir_p for use_localtime_mkdir when use use_localtime_mkdir to create multi level dir, ffmpeg give error message: ffmpeg -re -i ~/Movies/objectC/facebook.mp4 -c copy -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d/%s.ts' out.m3u8 error message: Could not create directory 20160926/file-20160926 with use_localtime_mkdir add mkdir_p for support the multi level dir Reviewed-by: Michael Niedermayer Tested-by: Zuo Genyu <1515161258@qq.com> (Windows) Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 428bae4377..c1619373bf 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -133,6 +133,39 @@ typedef struct HLSContext { double initial_prog_date_time; } HLSContext; +static int mkdir_p(const char *path) { + int ret = 0; + char *temp = av_strdup(path); + char *pos = temp; + char tmp_ch = '\0'; + + if (!path || !temp) { + return -1; + } + + if (!strncmp(temp, "/", 1) || !strncmp(temp, "\\", 1)) { + pos++; + } else if (!strncmp(temp, "./", 2) || !strncmp(temp, ".\\", 2)) { + pos += 2; + } + + for ( ; *pos != '\0'; ++pos) { + if (*pos == '/' || *pos == '\\') { + tmp_ch = *pos; + *pos = '\0'; + ret = mkdir(temp, 0755); + *pos = tmp_ch; + } + } + + if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) { + ret = mkdir(temp, 0755); + } + + av_free(temp); + return ret; +} + static int hls_delete_old_segments(HLSContext *hls) { HLSSegment *segment, *previous_segment = NULL; @@ -656,7 +689,7 @@ static int hls_start(AVFormatContext *s) return AVERROR(ENOMEM); } dir = av_dirname(fn_copy); - if (mkdir(dir, 0777) == -1 && errno != EEXIST) { + if (mkdir_p(dir) == -1 && errno != EEXIST) { av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir); av_free(fn_copy); return AVERROR(errno);