diff mbox series

[FFmpeg-devel] expand hls_fmp4_init_filename with strftime()

Message ID 5caf0509f793f014328149addf42bc6fea7edc9f.1602839609.git.nikis@pajkis.cz
State Superseded
Headers show
Series [FFmpeg-devel] expand hls_fmp4_init_filename with strftime() | expand

Checks

Context Check Description
andriy/PPC64_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Nikola Pajkovsky Oct. 22, 2020, 9:01 p.m. UTC
init.mp4 can be expanded with strftime() the same way as
hls_segment_filename.

Signed-off-by: Nikola Pajkovsky <nikis@pajkis.cz>
---
 doc/muxers.texi      |  7 ++++++
 libavformat/hlsenc.c | 52 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 48 insertions(+), 11 deletions(-)

Comments

Liu Steven Oct. 23, 2020, 1:10 a.m. UTC | #1
> 2020年10月23日 上午5:01,Nikola Pajkovsky <nikis@pajkis.cz> 写道:
> 
> init.mp4 can be expanded with strftime() the same way as
> hls_segment_filename.
> 
> Signed-off-by: Nikola Pajkovsky <nikis@pajkis.cz>
> ---
> doc/muxers.texi      |  7 ++++++
> libavformat/hlsenc.c | 52 ++++++++++++++++++++++++++++++++++----------
> 2 files changed, 48 insertions(+), 11 deletions(-)
> 
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index 813b4678f409..179b9239517b 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above.
> @item hls_fmp4_init_filename @var{filename}
> Set filename to the fragment files header file, default filename is @file{init.mp4}.
> 
> +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime.
> +@example
> +ffmpeg -i in.nut  -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8
> +@end example
> +This will produce init like this
> +@file{1602678741_init.mp4}
> +
> @item hls_fmp4_init_resend
> Resend init file after m3u8 file refresh every time, default is @var{0}.
> 
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index cb31d6aed7cf..691020cc6a46 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -258,6 +258,27 @@ typedef struct HLSContext {
>     int has_video_m3u8; /* has video stream m3u8 list */
> } HLSContext;
> 
> +static int strftime_expand(const char *fmt, char **dest)
> +{
> +    int r = 1;
> +    time_t now0;
> +    struct tm *tm, tmpbuf;
> +    char *buf;
> +
> +    buf = av_mallocz(MAX_URL_SIZE);
> +    if (!buf)
> +        return AVERROR(ENOMEM);
> +
> +    time(&now0);
> +    tm = localtime_r(&now0, &tmpbuf);
> +    r = strftime(buf, MAX_URL_SIZE, fmt, tm);
> +    if (!r)
> +        return AVERROR(EINVAL);
Should it memleak here or not? When the strftime return null.
> +    *dest = buf;
> +
> +    return r;
> +}
> +
> static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
>                           AVDictionary **options)
> {
> @@ -1614,19 +1635,15 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
>         ff_format_set_url(oc, filename);
>     } else {
>         if (c->use_localtime) {
> -            time_t now0;
> -            struct tm *tm, tmpbuf;
> -            int bufsize = strlen(vs->basename) + MAX_URL_SIZE;
> -            char *buf = av_mallocz(bufsize);
> -            if (!buf)
> -                return AVERROR(ENOMEM);
> -            time(&now0);
> -            tm = localtime_r(&now0, &tmpbuf);
> -            ff_format_set_url(oc, buf);
> -            if (!strftime(oc->url, bufsize, vs->basename, tm)) {
> +            int r;
> +            char *expanded = NULL;
> +
> +            r = strftime_expand(vs->basename, &expanded);
> +            if (r < 0) {
>                 av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
> -                return AVERROR(EINVAL);
> +                return r;
>             }
> +            ff_format_set_url(oc, expanded);
> 
>             err = sls_flag_use_localtime_filename(oc, c, vs);
>             if (err < 0) {
> @@ -2929,6 +2946,19 @@ static int hls_init(AVFormatContext *s)
>                         return ret;
>                 }
> 
> +                if (hls->use_localtime) {
> +                    int r;
> +                    char *expanded = NULL;
> +
> +                    r = strftime_expand(vs->fmp4_init_filename, &expanded);
> +                    if (r < 0) {
> +                      av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
> +                      return r;
> +		    }
> +		    av_free(vs->fmp4_init_filename);
> +		    vs->fmp4_init_filename = expanded;
> +		}
> +
>                 p = strrchr(vs->m3u8_name, '/');
>                 if (p) {
>                     char tmp = *(++p);
> -- 
> 2.28.0
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

Thanks

Steven Liu
Nikola Pajkovsky Oct. 23, 2020, 6:02 a.m. UTC | #2
Steven Liu <lq@chinaffmpeg.org> writes:

>> 2020年10月23日 上午5:01,Nikola Pajkovsky <nikis@pajkis.cz> 写道:
>> 
>> init.mp4 can be expanded with strftime() the same way as
>> hls_segment_filename.
>> 
>> Signed-off-by: Nikola Pajkovsky <nikis@pajkis.cz>
>> ---
>> doc/muxers.texi      |  7 ++++++
>> libavformat/hlsenc.c | 52 ++++++++++++++++++++++++++++++++++----------
>> 2 files changed, 48 insertions(+), 11 deletions(-)
>> 
>> diff --git a/doc/muxers.texi b/doc/muxers.texi
>> index 813b4678f409..179b9239517b 100644
>> --- a/doc/muxers.texi
>> +++ b/doc/muxers.texi
>> @@ -859,6 +859,13 @@ fmp4 files may be used in HLS version 7 and above.
>> @item hls_fmp4_init_filename @var{filename}
>> Set filename to the fragment files header file, default filename is @file{init.mp4}.
>> 
>> +Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime.
>> +@example
>> +ffmpeg -i in.nut  -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8
>> +@end example
>> +This will produce init like this
>> +@file{1602678741_init.mp4}
>> +
>> @item hls_fmp4_init_resend
>> Resend init file after m3u8 file refresh every time, default is @var{0}.
>> 
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index cb31d6aed7cf..691020cc6a46 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -258,6 +258,27 @@ typedef struct HLSContext {
>>     int has_video_m3u8; /* has video stream m3u8 list */
>> } HLSContext;
>> 
>> +static int strftime_expand(const char *fmt, char **dest)
>> +{
>> +    int r = 1;
>> +    time_t now0;
>> +    struct tm *tm, tmpbuf;
>> +    char *buf;
>> +
>> +    buf = av_mallocz(MAX_URL_SIZE);
>> +    if (!buf)
>> +        return AVERROR(ENOMEM);
>> +
>> +    time(&now0);
>> +    tm = localtime_r(&now0, &tmpbuf);
>> +    r = strftime(buf, MAX_URL_SIZE, fmt, tm);
>> +    if (!r)
>> +        return AVERROR(EINVAL);
> Should it memleak here or not? When the strftime return null.

Good catch. It's been while, since I wrote something in C. I'll
prepare v2.
diff mbox series

Patch

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 813b4678f409..179b9239517b 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -859,6 +859,13 @@  fmp4 files may be used in HLS version 7 and above.
 @item hls_fmp4_init_filename @var{filename}
 Set filename to the fragment files header file, default filename is @file{init.mp4}.
 
+Use @code{-strftime 1} on @var{filename} to expand the segment filename with localtime.
+@example
+ffmpeg -i in.nut  -hls_segment_type fmp4 -strftime 1 -hls_fmp4_init_filename "%s_init.mp4" out.m3u8
+@end example
+This will produce init like this
+@file{1602678741_init.mp4}
+
 @item hls_fmp4_init_resend
 Resend init file after m3u8 file refresh every time, default is @var{0}.
 
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index cb31d6aed7cf..691020cc6a46 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -258,6 +258,27 @@  typedef struct HLSContext {
     int has_video_m3u8; /* has video stream m3u8 list */
 } HLSContext;
 
+static int strftime_expand(const char *fmt, char **dest)
+{
+    int r = 1;
+    time_t now0;
+    struct tm *tm, tmpbuf;
+    char *buf;
+
+    buf = av_mallocz(MAX_URL_SIZE);
+    if (!buf)
+        return AVERROR(ENOMEM);
+
+    time(&now0);
+    tm = localtime_r(&now0, &tmpbuf);
+    r = strftime(buf, MAX_URL_SIZE, fmt, tm);
+    if (!r)
+        return AVERROR(EINVAL);
+    *dest = buf;
+
+    return r;
+}
+
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
                           AVDictionary **options)
 {
@@ -1614,19 +1635,15 @@  static int hls_start(AVFormatContext *s, VariantStream *vs)
         ff_format_set_url(oc, filename);
     } else {
         if (c->use_localtime) {
-            time_t now0;
-            struct tm *tm, tmpbuf;
-            int bufsize = strlen(vs->basename) + MAX_URL_SIZE;
-            char *buf = av_mallocz(bufsize);
-            if (!buf)
-                return AVERROR(ENOMEM);
-            time(&now0);
-            tm = localtime_r(&now0, &tmpbuf);
-            ff_format_set_url(oc, buf);
-            if (!strftime(oc->url, bufsize, vs->basename, tm)) {
+            int r;
+            char *expanded = NULL;
+
+            r = strftime_expand(vs->basename, &expanded);
+            if (r < 0) {
                 av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
-                return AVERROR(EINVAL);
+                return r;
             }
+            ff_format_set_url(oc, expanded);
 
             err = sls_flag_use_localtime_filename(oc, c, vs);
             if (err < 0) {
@@ -2929,6 +2946,19 @@  static int hls_init(AVFormatContext *s)
                         return ret;
                 }
 
+                if (hls->use_localtime) {
+                    int r;
+                    char *expanded = NULL;
+
+                    r = strftime_expand(vs->fmp4_init_filename, &expanded);
+                    if (r < 0) {
+                      av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
+                      return r;
+		    }
+		    av_free(vs->fmp4_init_filename);
+		    vs->fmp4_init_filename = expanded;
+		}
+
                 p = strrchr(vs->m3u8_name, '/');
                 if (p) {
                     char tmp = *(++p);