diff mbox

[FFmpeg-devel] avformat/hlsenc: second_levels flags process function extract

Message ID 20170311043124.23312-1-lq@chinaffmpeg.org
State Accepted
Commit 33e997d992ccd4e93b57fa7dfb478fc6a67ce4ac
Headers show

Commit Message

Liu Steven March 11, 2017, 4:31 a.m. UTC
the SECOND_LEVEL* flags process and name is too long
extract all of them output to funtions, make code clear

Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
 libavformat/hlsenc.c | 239 +++++++++++++++++++++++++++++----------------------
 1 file changed, 136 insertions(+), 103 deletions(-)

Comments

Steven Liu March 13, 2017, 4:04 a.m. UTC | #1
2017-03-11 12:31 GMT+08:00 Steven Liu <lq@chinaffmpeg.org>:

> the SECOND_LEVEL* flags process and name is too long
> extract all of them output to funtions, make code clear
>
> Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> ---
>  libavformat/hlsenc.c | 239 +++++++++++++++++++++++++++++-
> ---------------------
>  1 file changed, 136 insertions(+), 103 deletions(-)
>
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index b8122f1..5df2514 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -470,17 +470,9 @@ static HLSSegment *find_segment_by_filename(HLSSegment
> *segment, const char *fil
>      return (HLSSegment *) NULL;
>  }
>
> -/* Create a new segment and append it to the segment list */
> -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
> double duration,
> -                              int64_t pos, int64_t size)
> +static int sls_flags_filename_process(struct AVFormatContext *s,
> HLSContext *hls, HLSSegment *en, double duration,
> +                                         int64_t pos, int64_t size)
>  {
> -    HLSSegment *en = av_malloc(sizeof(*en));
> -    const char  *filename;
> -    int ret;
> -
> -    if (!en)
> -        return AVERROR(ENOMEM);
> -
>      if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
>          strlen(hls->current_segment_final_filename_fmt)) {
>          av_strlcpy(hls->avf->filename, hls->current_segment_final_filename_fmt,
> sizeof(hls->avf->filename));
> @@ -521,7 +513,127 @@ static int hls_append_segment(struct AVFormatContext
> *s, HLSContext *hls, double
>              av_free(filename);
>          }
>      }
> +    return 0;
> +}
> +
> +static int sls_flag_check_duration_size_index(HLSContext *hls)
> +{
> +    int ret = 0;
> +
> +    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
> +         av_log(hls, AV_LOG_ERROR,
> +                "second_level_segment_duration hls_flag requires
> use_localtime to be true\n");
> +         ret = AVERROR(EINVAL);
> +    }
> +    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
> +         av_log(hls, AV_LOG_ERROR,
> +                "second_level_segment_size hls_flag requires
> use_localtime to be true\n");
> +         ret = AVERROR(EINVAL);
> +    }
> +    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
> +        av_log(hls, AV_LOG_ERROR,
> +               "second_level_segment_index hls_flag requires
> use_localtime to be true\n");
> +        ret = AVERROR(EINVAL);
> +    }
> +
> +    return ret;
> +}
> +
> +static int sls_flag_check_duration_size(HLSContext *hls)
> +{
> +    const char *proto = avio_find_protocol_name(hls->basename);
> +    int segment_renaming_ok = proto && !strcmp(proto, "file");
> +    int ret = 0;
> +
> +    if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) &&
> !segment_renaming_ok) {
> +         av_log(hls, AV_LOG_ERROR,
> +                "second_level_segment_duration hls_flag works only with
> file protocol segment names\n");
> +         ret = AVERROR(EINVAL);
> +    }
> +    if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) &&
> !segment_renaming_ok) {
> +         av_log(hls, AV_LOG_ERROR,
> +                "second_level_segment_size hls_flag works only with file
> protocol segment names\n");
> +         ret = AVERROR(EINVAL);
> +    }
> +
> +    return ret;
> +}
> +
> +static void sls_flag_file_rename(HLSContext *hls, char *old_filename) {
> +    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
> +        strlen(hls->current_segment_final_filename_fmt)) {
> +        ff_rename(old_filename, hls->avf->filename, hls);
> +    }
> +}
> +
> +static int sls_flag_use_localtime_filename(AVFormatContext *oc,
> HLSContext *c)
> +{
> +    if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
> +        char * filename = av_strdup(oc->filename);  // %%d will be %d
> after strftime
> +        if (!filename)
> +            return AVERROR(ENOMEM);
> +        if (replace_int_data_in_filename(oc->filename,
> sizeof(oc->filename),
> +#if FF_API_HLS_WRAP
> +            filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence)
> < 1) {
> +#else
> +            filename, 'd', c->sequence) < 1) {
> +#endif
> +            av_log(c, AV_LOG_ERROR, "Invalid second level segment
> filename template '%s', "
> +                    "you can try to remove second_level_segment_index
> flag\n",
> +                   filename);
> +            av_free(filename);
> +            return AVERROR(EINVAL);
> +        }
> +        av_free(filename);
> +    }
> +    if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
> +        av_strlcpy(c->current_segment_final_filename_fmt, oc->filename,
> +                   sizeof(c->current_segment_final_filename_fmt));
> +        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
> +            char * filename = av_strdup(oc->filename);  // %%s will be %s
> after strftime
> +            if (!filename)
> +                return AVERROR(ENOMEM);
> +            if (replace_int_data_in_filename(oc->filename,
> sizeof(oc->filename), filename, 's', 0) < 1) {
> +                av_log(c, AV_LOG_ERROR, "Invalid second level segment
> filename template '%s', "
> +                        "you can try to remove second_level_segment_size
> flag\n",
> +                       filename);
> +                av_free(filename);
> +                return AVERROR(EINVAL);
> +            }
> +            av_free(filename);
> +        }
> +        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
> +            char * filename = av_strdup(oc->filename);  // %%t will be %t
> after strftime
> +            if (!filename)
> +                return AVERROR(ENOMEM);
> +            if (replace_int_data_in_filename(oc->filename,
> sizeof(oc->filename), filename, 't', 0) < 1) {
> +                av_log(c, AV_LOG_ERROR, "Invalid second level segment
> filename template '%s', "
> +                        "you can try to remove second_level_segment_time
> flag\n",
> +                       filename);
> +                av_free(filename);
> +                return AVERROR(EINVAL);
> +            }
> +            av_free(filename);
> +        }
> +    }
> +    return 0;
> +}
> +
> +/* Create a new segment and append it to the segment list */
> +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
> double duration,
> +                              int64_t pos, int64_t size)
> +{
> +    HLSSegment *en = av_malloc(sizeof(*en));
> +    const char  *filename;
> +    int ret;
>
> +    if (!en)
> +        return AVERROR(ENOMEM);
> +
> +    ret = sls_flags_filename_process(s, hls, en, duration, pos, size);
> +    if (ret < 0) {
> +        return ret;
> +    }
>
>      filename = av_basename(hls->avf->filename);
>
> @@ -870,57 +982,12 @@ static int hls_start(AVFormatContext *s)
>                  av_log(oc, AV_LOG_ERROR, "Could not get segment filename
> with use_localtime\n");
>                  return AVERROR(EINVAL);
>              }
> -            if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
> -                char * filename = av_strdup(oc->filename);  // %%d will
> be %d after strftime
> -                if (!filename)
> -                    return AVERROR(ENOMEM);
> -                if (replace_int_data_in_filename(oc->filename,
> sizeof(oc->filename),
> -#if FF_API_HLS_WRAP
> -                    filename, 'd', c->wrap ? c->sequence % c->wrap :
> c->sequence) < 1) {
> -#else
> -                    filename, 'd', c->sequence) < 1) {
> -#endif
> -                    av_log(c, AV_LOG_ERROR,
> -                           "Invalid second level segment filename
> template '%s', "
> -                            "you can try to remove
> second_level_segment_index flag\n",
> -                           filename);
> -                    av_free(filename);
> -                    return AVERROR(EINVAL);
> -                }
> -                av_free(filename);
> -            }
> -            if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
> -                av_strlcpy(c->current_segment_final_filename_fmt,
> oc->filename,
> -                           sizeof(c->current_segment_
> final_filename_fmt));
> -                if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
> -                    char * filename = av_strdup(oc->filename);  // %%s
> will be %s after strftime
> -                    if (!filename)
> -                        return AVERROR(ENOMEM);
> -                    if (replace_int_data_in_filename(oc->filename,
> sizeof(oc->filename), filename, 's', 0) < 1) {
> -                        av_log(c, AV_LOG_ERROR,
> -                               "Invalid second level segment filename
> template '%s', "
> -                                "you can try to remove
> second_level_segment_size flag\n",
> -                               filename);
> -                        av_free(filename);
> -                        return AVERROR(EINVAL);
> -                    }
> -                    av_free(filename);
> -                }
> -                if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
> -                    char * filename = av_strdup(oc->filename);  // %%t
> will be %t after strftime
> -                    if (!filename)
> -                        return AVERROR(ENOMEM);
> -                    if (replace_int_data_in_filename(oc->filename,
> sizeof(oc->filename), filename, 't', 0) < 1) {
> -                        av_log(c, AV_LOG_ERROR,
> -                               "Invalid second level segment filename
> template '%s', "
> -                                "you can try to remove
> second_level_segment_time flag\n",
> -                               filename);
> -                        av_free(filename);
> -                        return AVERROR(EINVAL);
> -                    }
> -                    av_free(filename);
> -                }
> +
> +            err = sls_flag_use_localtime_filename(oc, c);
> +            if (err < 0) {
> +                return AVERROR(ENOMEM);
>              }
> +
>              if (c->use_localtime_mkdir) {
>                  const char *dir;
>                  char *fn_copy = av_strdup(oc->filename);
> @@ -1043,7 +1110,8 @@ static int hls_write_header(AVFormatContext *s)
>      int basename_size;
>      int vtt_basename_size;
>
> -    if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH
> || hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)
> {
> +    if ((hls->start_sequence_source_type ==
> HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
> +        (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME))
> {
>          time_t t = time(NULL); // we will need it in either case
>          if (hls->start_sequence_source_type ==
> HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
>              hls->start_sequence = (int64_t)t;
> @@ -1138,38 +1206,13 @@ static int hls_write_header(AVFormatContext *s)
>          }
>      }
>      if (!hls->use_localtime) {
> -        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
> -             av_log(hls, AV_LOG_ERROR,
> -                    "second_level_segment_duration hls_flag requires
> use_localtime to be true\n");
> -             ret = AVERROR(EINVAL);
> -             goto fail;
> -        }
> -        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
> -             av_log(hls, AV_LOG_ERROR,
> -                    "second_level_segment_size hls_flag requires
> use_localtime to be true\n");
> -             ret = AVERROR(EINVAL);
> +        ret = sls_flag_check_duration_size_index(hls);
> +        if (ret < 0) {
>               goto fail;
>          }
> -        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
> -            av_log(hls, AV_LOG_ERROR,
> -                   "second_level_segment_index hls_flag requires
> use_localtime to be true\n");
> -            ret = AVERROR(EINVAL);
> -            goto fail;
> -        }
>      } else {
> -        const char *proto = avio_find_protocol_name(hls->basename);
> -        int segment_renaming_ok = proto && !strcmp(proto, "file");
> -
> -        if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) &&
> !segment_renaming_ok) {
> -             av_log(hls, AV_LOG_ERROR,
> -                    "second_level_segment_duration hls_flag works only
> with file protocol segment names\n");
> -             ret = AVERROR(EINVAL);
> -             goto fail;
> -        }
> -        if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) &&
> !segment_renaming_ok) {
> -             av_log(hls, AV_LOG_ERROR,
> -                    "second_level_segment_size hls_flag works only with
> file protocol segment names\n");
> -             ret = AVERROR(EINVAL);
> +        ret = sls_flag_check_duration_size(hls);
> +        if (ret < 0) {
>               goto fail;
>          }
>      }
> @@ -1355,10 +1398,7 @@ static int hls_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>          } else if (hls->max_seg_size > 0) {
>              if (hls->start_pos >= hls->max_seg_size) {
>                  hls->sequence++;
> -                if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
> -                     strlen(hls->current_segment_final_filename_fmt)) {
> -                    ff_rename(old_filename, hls->avf->filename, hls);
> -                }
> +                sls_flag_file_rename(hls, old_filename);
>                  ret = hls_start(s);
>                  hls->start_pos = 0;
>                  /* When split segment by byte, the duration is short than
> hls_time,
> @@ -1367,11 +1407,7 @@ static int hls_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>              }
>              hls->number++;
>          } else {
> -            if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
> -                strlen(hls->current_segment_final_filename_fmt)) {
> -                ff_rename(old_filename, hls->avf->filename, hls);
> -            }
> -
> +            sls_flag_file_rename(hls, old_filename);
>              ret = hls_start(s);
>          }
>
> @@ -1416,10 +1452,7 @@ static int hls_write_trailer(struct AVFormatContext
> *s)
>          hls_append_segment(s, hls, hls->duration + hls->dpp,
> hls->start_pos, hls->size);
>      }
>
> -    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE |
> HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
> -         strlen(hls->current_segment_final_filename_fmt)) {
> -         ff_rename(old_filename, hls->avf->filename, hls);
> -    }
> +    sls_flag_file_rename(hls, old_filename);
>
>      if (vtt_oc) {
>          if (vtt_oc->pb)
> --
> 2.10.1.382.ga23ca1b.dirty
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

pushed


Thanks!
diff mbox

Patch

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index b8122f1..5df2514 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -470,17 +470,9 @@  static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *fil
     return (HLSSegment *) NULL;
 }
 
-/* Create a new segment and append it to the segment list */
-static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration,
-                              int64_t pos, int64_t size)
+static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls, HLSSegment *en, double duration,
+                                         int64_t pos, int64_t size)
 {
-    HLSSegment *en = av_malloc(sizeof(*en));
-    const char  *filename;
-    int ret;
-
-    if (!en)
-        return AVERROR(ENOMEM);
-
     if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
         strlen(hls->current_segment_final_filename_fmt)) {
         av_strlcpy(hls->avf->filename, hls->current_segment_final_filename_fmt, sizeof(hls->avf->filename));
@@ -521,7 +513,127 @@  static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double
             av_free(filename);
         }
     }
+    return 0;
+}
+
+static int sls_flag_check_duration_size_index(HLSContext *hls)
+{
+    int ret = 0;
+
+    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
+         av_log(hls, AV_LOG_ERROR,
+                "second_level_segment_duration hls_flag requires use_localtime to be true\n");
+         ret = AVERROR(EINVAL);
+    }
+    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
+         av_log(hls, AV_LOG_ERROR,
+                "second_level_segment_size hls_flag requires use_localtime to be true\n");
+         ret = AVERROR(EINVAL);
+    }
+    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
+        av_log(hls, AV_LOG_ERROR,
+               "second_level_segment_index hls_flag requires use_localtime to be true\n");
+        ret = AVERROR(EINVAL);
+    }
+
+    return ret;
+}
+
+static int sls_flag_check_duration_size(HLSContext *hls)
+{
+    const char *proto = avio_find_protocol_name(hls->basename);
+    int segment_renaming_ok = proto && !strcmp(proto, "file");
+    int ret = 0;
+
+    if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
+         av_log(hls, AV_LOG_ERROR,
+                "second_level_segment_duration hls_flag works only with file protocol segment names\n");
+         ret = AVERROR(EINVAL);
+    }
+    if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
+         av_log(hls, AV_LOG_ERROR,
+                "second_level_segment_size hls_flag works only with file protocol segment names\n");
+         ret = AVERROR(EINVAL);
+    }
+
+    return ret;
+}
+
+static void sls_flag_file_rename(HLSContext *hls, char *old_filename) {
+    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
+        strlen(hls->current_segment_final_filename_fmt)) {
+        ff_rename(old_filename, hls->avf->filename, hls);
+    }
+}
+
+static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c)
+{
+    if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
+        char * filename = av_strdup(oc->filename);  // %%d will be %d after strftime
+        if (!filename)
+            return AVERROR(ENOMEM);
+        if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
+#if FF_API_HLS_WRAP
+            filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
+#else
+            filename, 'd', c->sequence) < 1) {
+#endif
+            av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
+                    "you can try to remove second_level_segment_index flag\n",
+                   filename);
+            av_free(filename);
+            return AVERROR(EINVAL);
+        }
+        av_free(filename);
+    }
+    if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
+        av_strlcpy(c->current_segment_final_filename_fmt, oc->filename,
+                   sizeof(c->current_segment_final_filename_fmt));
+        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
+            char * filename = av_strdup(oc->filename);  // %%s will be %s after strftime
+            if (!filename)
+                return AVERROR(ENOMEM);
+            if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) {
+                av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
+                        "you can try to remove second_level_segment_size flag\n",
+                       filename);
+                av_free(filename);
+                return AVERROR(EINVAL);
+            }
+            av_free(filename);
+        }
+        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
+            char * filename = av_strdup(oc->filename);  // %%t will be %t after strftime
+            if (!filename)
+                return AVERROR(ENOMEM);
+            if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) {
+                av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
+                        "you can try to remove second_level_segment_time flag\n",
+                       filename);
+                av_free(filename);
+                return AVERROR(EINVAL);
+            }
+            av_free(filename);
+        }
+    }
+    return 0;
+}
+
+/* Create a new segment and append it to the segment list */
+static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration,
+                              int64_t pos, int64_t size)
+{
+    HLSSegment *en = av_malloc(sizeof(*en));
+    const char  *filename;
+    int ret;
 
+    if (!en)
+        return AVERROR(ENOMEM);
+
+    ret = sls_flags_filename_process(s, hls, en, duration, pos, size);
+    if (ret < 0) {
+        return ret;
+    }
 
     filename = av_basename(hls->avf->filename);
 
@@ -870,57 +982,12 @@  static int hls_start(AVFormatContext *s)
                 av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n");
                 return AVERROR(EINVAL);
             }
-            if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
-                char * filename = av_strdup(oc->filename);  // %%d will be %d after strftime
-                if (!filename)
-                    return AVERROR(ENOMEM);
-                if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
-#if FF_API_HLS_WRAP
-                    filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
-#else
-                    filename, 'd', c->sequence) < 1) {
-#endif
-                    av_log(c, AV_LOG_ERROR,
-                           "Invalid second level segment filename template '%s', "
-                            "you can try to remove second_level_segment_index flag\n",
-                           filename);
-                    av_free(filename);
-                    return AVERROR(EINVAL);
-                }
-                av_free(filename);
-            }
-            if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
-                av_strlcpy(c->current_segment_final_filename_fmt, oc->filename,
-                           sizeof(c->current_segment_final_filename_fmt));
-                if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
-                    char * filename = av_strdup(oc->filename);  // %%s will be %s after strftime
-                    if (!filename)
-                        return AVERROR(ENOMEM);
-                    if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) {
-                        av_log(c, AV_LOG_ERROR,
-                               "Invalid second level segment filename template '%s', "
-                                "you can try to remove second_level_segment_size flag\n",
-                               filename);
-                        av_free(filename);
-                        return AVERROR(EINVAL);
-                    }
-                    av_free(filename);
-                }
-                if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
-                    char * filename = av_strdup(oc->filename);  // %%t will be %t after strftime
-                    if (!filename)
-                        return AVERROR(ENOMEM);
-                    if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) {
-                        av_log(c, AV_LOG_ERROR,
-                               "Invalid second level segment filename template '%s', "
-                                "you can try to remove second_level_segment_time flag\n",
-                               filename);
-                        av_free(filename);
-                        return AVERROR(EINVAL);
-                    }
-                    av_free(filename);
-                }
+
+            err = sls_flag_use_localtime_filename(oc, c);
+            if (err < 0) {
+                return AVERROR(ENOMEM);
             }
+
             if (c->use_localtime_mkdir) {
                 const char *dir;
                 char *fn_copy = av_strdup(oc->filename);
@@ -1043,7 +1110,8 @@  static int hls_write_header(AVFormatContext *s)
     int basename_size;
     int vtt_basename_size;
 
-    if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH || hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
+    if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
+        (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
         time_t t = time(NULL); // we will need it in either case
         if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
             hls->start_sequence = (int64_t)t;
@@ -1138,38 +1206,13 @@  static int hls_write_header(AVFormatContext *s)
         }
     }
     if (!hls->use_localtime) {
-        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
-             av_log(hls, AV_LOG_ERROR,
-                    "second_level_segment_duration hls_flag requires use_localtime to be true\n");
-             ret = AVERROR(EINVAL);
-             goto fail;
-        }
-        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
-             av_log(hls, AV_LOG_ERROR,
-                    "second_level_segment_size hls_flag requires use_localtime to be true\n");
-             ret = AVERROR(EINVAL);
+        ret = sls_flag_check_duration_size_index(hls);
+        if (ret < 0) {
              goto fail;
         }
-        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
-            av_log(hls, AV_LOG_ERROR,
-                   "second_level_segment_index hls_flag requires use_localtime to be true\n");
-            ret = AVERROR(EINVAL);
-            goto fail;
-        }
     } else {
-        const char *proto = avio_find_protocol_name(hls->basename);
-        int segment_renaming_ok = proto && !strcmp(proto, "file");
-
-        if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
-             av_log(hls, AV_LOG_ERROR,
-                    "second_level_segment_duration hls_flag works only with file protocol segment names\n");
-             ret = AVERROR(EINVAL);
-             goto fail;
-        }
-        if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
-             av_log(hls, AV_LOG_ERROR,
-                    "second_level_segment_size hls_flag works only with file protocol segment names\n");
-             ret = AVERROR(EINVAL);
+        ret = sls_flag_check_duration_size(hls);
+        if (ret < 0) {
              goto fail;
         }
     }
@@ -1355,10 +1398,7 @@  static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
         } else if (hls->max_seg_size > 0) {
             if (hls->start_pos >= hls->max_seg_size) {
                 hls->sequence++;
-                if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
-                     strlen(hls->current_segment_final_filename_fmt)) {
-                    ff_rename(old_filename, hls->avf->filename, hls);
-                }
+                sls_flag_file_rename(hls, old_filename);
                 ret = hls_start(s);
                 hls->start_pos = 0;
                 /* When split segment by byte, the duration is short than hls_time,
@@ -1367,11 +1407,7 @@  static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
             }
             hls->number++;
         } else {
-            if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
-                strlen(hls->current_segment_final_filename_fmt)) {
-                ff_rename(old_filename, hls->avf->filename, hls);
-            }
-
+            sls_flag_file_rename(hls, old_filename);
             ret = hls_start(s);
         }
 
@@ -1416,10 +1452,7 @@  static int hls_write_trailer(struct AVFormatContext *s)
         hls_append_segment(s, hls, hls->duration + hls->dpp, hls->start_pos, hls->size);
     }
 
-    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
-         strlen(hls->current_segment_final_filename_fmt)) {
-         ff_rename(old_filename, hls->avf->filename, hls);
-    }
+    sls_flag_file_rename(hls, old_filename);
 
     if (vtt_oc) {
         if (vtt_oc->pb)