diff mbox

[FFmpeg-devel] libavformat/segment: strftime date sub-directories

Message ID CAAMvbhFSoCw9QbWJ=ZKas6T7RiQR048Cc0fzo_kZFOwgEOK1Ww@mail.gmail.com
State Superseded
Headers show

Commit Message

James Dutton Sept. 24, 2018, 11:39 a.m. UTC

Comments

Moritz Barsnick Sept. 24, 2018, 12:48 p.m. UTC | #1
On Mon, Sep 24, 2018 at 12:39:42 +0100, James Courtier-Dutton wrote:

> Automatically create sub-directories if needed based on date.
> E.g.
> ffmpeg ... -timelimit 2147483647 -f segment -strftime 1 -segment_time 10 "%Y/%m/%d/%Y-%m-%d_%H-%M-%S.mkv"
[...]
> +static int mkdir_p(const char *path) {

Is this code duplicated from libavformat/hlsenc.c?

I don't know what the policy is, and how code from hls vs. segment has
been deduplicated previously, but it seems like this is a candidate for
being careful.

Moritz
James Dutton Sept. 24, 2018, 6:58 p.m. UTC | #2
On 24 September 2018 at 13:48, Moritz Barsnick <barsnick@gmx.net> wrote:

> On Mon, Sep 24, 2018 at 12:39:42 +0100, James Courtier-Dutton wrote:
>
> > Automatically create sub-directories if needed based on date.
> > E.g.
> > ffmpeg ... -timelimit 2147483647 -f segment -strftime 1 -segment_time 10
> "%Y/%m/%d/%Y-%m-%d_%H-%M-%S.mkv"
> [...]
> > +static int mkdir_p(const char *path) {
>
> Is this code duplicated from libavformat/hlsenc.c?
>
> I don't know what the policy is, and how code from hls vs. segment has
> been deduplicated previously, but it seems like this is a candidate for
> being careful.
>
>
It is a duplicate from hisenc.c.  hisenc already has this "create
sub-directories" feature, but I needed it for the segment use case.
I made it static so that it would be treated as local to the .c file.
I don't know ffmpeg well enough to know how best to de-duplicate it.
I am happy to update my patch, if someone can give me a pointer as to what
to do.

Kind Regards

James
Jeyapal, Karthick Sept. 25, 2018, 8:49 a.m. UTC | #3
On 9/25/18 12:28 AM, James Courtier-Dutton wrote:
> On 24 September 2018 at 13:48, Moritz Barsnick <barsnick@gmx.net> wrote:

>

>> On Mon, Sep 24, 2018 at 12:39:42 +0100, James Courtier-Dutton wrote:

>>

>>> Automatically create sub-directories if needed based on date.

>>> E.g.

>>> ffmpeg ... -timelimit 2147483647 -f segment -strftime 1 -segment_time 10

>> "%Y/%m/%d/%Y-%m-%d_%H-%M-%S.mkv"

>> [...]

>>> +static int mkdir_p(const char *path) {

>>

>> Is this code duplicated from libavformat/hlsenc.c?

>>

>> I don't know what the policy is, and how code from hls vs. segment has

>> been deduplicated previously, but it seems like this is a candidate for

>> being careful.

>>

>>

> It is a duplicate from hisenc.c.  hisenc already has this "create

> sub-directories" feature, but I needed it for the segment use case.

> I made it static so that it would be treated as local to the .c file.

> I don't know ffmpeg well enough to know how best to de-duplicate it.

> I am happy to update my patch, if someone can give me a pointer as to what

> to do.


When faced with a similar situation, I created a new file(.c and .h) with those function made global within libavformat(prefix it with ff_).
Then these functions could be used by both hlsenc.c and other files inside the libavformat library. 
You could refer to below commit as a pointer
https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/da49cdf6401ea3caa616c226f24dfb407633acd0

>

> Kind Regards

>

> James

> _______________________________________________

> ffmpeg-devel mailing list

> ffmpeg-devel@ffmpeg.org

> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Moritz Barsnick Sept. 25, 2018, 9:22 a.m. UTC | #4
On Tue, Sep 25, 2018 at 08:49:25 +0000, Jeyapal, Karthick wrote:
> > It is a duplicate from hisenc.c.  hisenc already has this "create
> > sub-directories" feature, but I needed it for the segment use case.
> > I made it static so that it would be treated as local to the .c file.
> > I don't know ffmpeg well enough to know how best to de-duplicate it.
> > I am happy to update my patch, if someone can give me a pointer as to what
> > to do.
> 
> When faced with a similar situation, I created a new file(.c and .h) with those function made global within libavformat(prefix it with ff_).
> Then these functions could be used by both hlsenc.c and other files inside the libavformat library. 
> You could refer to below commit as a pointer
> https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/da49cdf6401ea3caa616c226f24dfb407633acd0

Steven already posted a patch proposal to this list, factoring out the
function:
https://patchwork.ffmpeg.org/patch/10471/
http://ffmpeg.org/pipermail/ffmpeg-devel/2018-September/234538.html

Moritz
James Dutton Sept. 25, 2018, 12:33 p.m. UTC | #5
On 25 September 2018 at 10:22, Moritz Barsnick <barsnick@gmx.net> wrote:

>
> Steven already posted a patch proposal to this list, factoring out the
> function:
> https://patchwork.ffmpeg.org/patch/10471/
> http://ffmpeg.org/pipermail/ffmpeg-devel/2018-September/234538.html
>
>
That looks fine by me. I can resubmit my segment.c patch once 10471 reaches
master tree or at least somewhere I can cherry pick from.

Kind Regards

James
Liu Steven Sept. 25, 2018, 2 p.m. UTC | #6
> On Sep 25, 2018, at 20:33, James Courtier-Dutton <james.dutton@gmail.com> wrote:
> 
> On 25 September 2018 at 10:22, Moritz Barsnick <barsnick@gmx.net> wrote:
> 
>> 
>> Steven already posted a patch proposal to this list, factoring out the
>> function:
>> https://patchwork.ffmpeg.org/patch/10471/
>> http://ffmpeg.org/pipermail/ffmpeg-devel/2018-September/234538.html
>> 
>> 
> That looks fine by me. I can resubmit my segment.c patch once 10471 reaches
> master tree or at least somewhere I can cherry pick from.
> 
> Kind Regards
> 
> James
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Okay, you can go on do this, i have pushed that patch.

Thanks
Steven
diff mbox

Patch

From 6c74670e047bfc9e995c0f968c1688be768d13bd Mon Sep 17 00:00:00 2001
From: James Courtier-Dutton <James.Dutton@gmail.com>
Date: Mon, 24 Sep 2018 12:34:54 +0100
Subject: [PATCH] avformat/segment: strftime date sub-directories

Automatically create sub-directories if needed based on date.
E.g.
ffmpeg ... -timelimit 2147483647 -f segment -strftime 1 -segment_time 10 "%Y/%m/%d/%Y-%m-%d_%H-%M-%S.mkv"

Signed-off-by: James Courtier-Dutton <James.Dutton@gmail.com>
---
 libavformat/segment.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/libavformat/segment.c b/libavformat/segment.c
index 7fb4dc7..b2300d9 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -186,6 +186,39 @@  static int segment_mux_init(AVFormatContext *s)
     return 0;
 }
 
+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 set_segment_filename(AVFormatContext *s)
 {
     SegmentContext *seg = s->priv_data;
@@ -200,12 +233,27 @@  static int set_segment_filename(AVFormatContext *s)
     if (seg->use_strftime) {
         time_t now0;
         struct tm *tm, tmpbuf;
+        const char *dir;
+        char *fn_copy;
         time(&now0);
         tm = localtime_r(&now0, &tmpbuf);
         if (!strftime(buf, sizeof(buf), s->url, tm)) {
             av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
             return AVERROR(EINVAL);
         }
+        /* Automatically create directories if needed */
+        /* E.g. %Y/%m/%d/%Y-%m-%d_%H-%M-%S.mkv */
+        fn_copy = av_strdup(buf);
+        if (!fn_copy) {
+            return AVERROR(ENOMEM);
+        }
+        dir = av_dirname(fn_copy);
+        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);
+        }
+        av_free(fn_copy);
     } else if (av_get_frame_filename(buf, sizeof(buf),
                                      s->url, seg->segment_idx) < 0) {
         av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->url);
-- 
2.7.4