Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified
@ 2023-10-27  3:59 Dave Johansen
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 2/4] avformat/hlsenc: Add strftime_prog for using PROGRAM-DATE-TIME in the segment filename Dave Johansen
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Dave Johansen @ 2023-10-27  3:59 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Dave Johansen

---
 doc/muxers.texi      |  3 +++
 libavformat/hlsenc.c | 41 +++++++++++++++++++++++++----------------
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index f6071484ff..87c19a5cb9 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1086,6 +1086,9 @@ seeking. This flag should be used with the @code{hls_time} option.
 @item program_date_time
 Generate @code{EXT-X-PROGRAM-DATE-TIME} tags.
 
+@item init_program_date_time
+Time to start program date time at.
+
 @item second_level_segment_index
 Makes it possible to use segment indexes as %%d in hls_segment_filename expression
 besides date/time values when strftime is on.
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 4ef84c05c1..5dfff6b2b6 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -212,6 +212,8 @@ typedef struct HLSContext {
     int64_t recording_time;
     int64_t max_seg_size; // every segment file max size
 
+    char *init_program_date_time;
+
     char *baseurl;
     char *vtt_format_options_str;
     char *subtitle_filename;
@@ -1192,6 +1194,25 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
     return 0;
 }
 
+static double parse_iso8601(const char *ptr) {
+    struct tm program_date_time;
+    int y,M,d,h,m,s;
+    double ms;
+    if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) {
+        return -1;
+    }
+
+    program_date_time.tm_year = y - 1900;
+    program_date_time.tm_mon = M - 1;
+    program_date_time.tm_mday = d;
+    program_date_time.tm_hour = h;
+    program_date_time.tm_min = m;
+    program_date_time.tm_sec = s;
+    program_date_time.tm_isdst = -1;
+
+    return mktime(&program_date_time) + (double)(ms / 1000);
+}
+
 static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
 {
     HLSContext *hls = s->priv_data;
@@ -1257,24 +1278,11 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
                 }
             }
         } else if (av_strstart(line, "#EXT-X-PROGRAM-DATE-TIME:", &ptr)) {
-            struct tm program_date_time;
-            int y,M,d,h,m,s;
-            double ms;
-            if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) {
+            discont_program_date_time = parse_iso8601(ptr);
+            if (discont_program_date_time < 0) {
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
-
-            program_date_time.tm_year = y - 1900;
-            program_date_time.tm_mon = M - 1;
-            program_date_time.tm_mday = d;
-            program_date_time.tm_hour = h;
-            program_date_time.tm_min = m;
-            program_date_time.tm_sec = s;
-            program_date_time.tm_isdst = -1;
-
-            discont_program_date_time = mktime(&program_date_time);
-            discont_program_date_time += (double)(ms / 1000);
         } else if (av_strstart(line, "#", NULL)) {
             continue;
         } else if (line[0]) {
@@ -2867,7 +2875,7 @@ static int hls_init(AVFormatContext *s)
     char *p = NULL;
     int http_base_proto = ff_is_http_proto(s->url);
     int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
-    double initial_program_date_time = av_gettime() / 1000000.0;
+    double initial_program_date_time = hls->init_program_date_time ? parse_iso8601(hls->init_program_date_time) : av_gettime() / 1000000.0;
 
     if (hls->use_localtime) {
         pattern = get_default_pattern_localtime_fmt(s);
@@ -3141,6 +3149,7 @@ static const AVOption options[] = {
     {"split_by_time", "split the hls segment by time which user set by hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX,   E, "flags"},
     {"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX,   E, "flags"},
     {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX,   E, "flags"},
+    {"init_program_date_time", "Time to start program date time at", OFFSET(init_program_date_time), AV_OPT_TYPE_STRING, .flags = E},
     {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX,   E, "flags"},
-- 
2.39.2 (Apple Git-143)

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [FFmpeg-devel] [PATCH 2/4] avformat/hlsenc: Add strftime_prog for using PROGRAM-DATE-TIME in the segment filename
  2023-10-27  3:59 [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified Dave Johansen
@ 2023-10-27  3:59 ` Dave Johansen
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message Dave Johansen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Dave Johansen @ 2023-10-27  3:59 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Dave Johansen

---
 libavformat/hlsenc.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 5dfff6b2b6..24a0304f78 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -159,6 +159,7 @@ typedef struct VariantStream {
     char *m3u8_name;
 
     double initial_prog_date_time;
+    double curr_prog_date_time;
     char current_segment_final_filename_fmt[MAX_URL_SIZE]; // when renaming segments
 
     char *fmp4_init_filename;
@@ -208,6 +209,7 @@ typedef struct HLSContext {
 
     int use_localtime;      ///< flag to expand filename with localtime
     int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename
+    int use_localtime_prog; ///< flag to expand filename with prog date time
     int allowcache;
     int64_t recording_time;
     int64_t max_seg_size; // every segment file max size
@@ -259,10 +261,9 @@ typedef struct HLSContext {
     int has_video_m3u8; /* has video stream m3u8 list */
 } HLSContext;
 
-static int strftime_expand(const char *fmt, char **dest)
+static int strftime_expand_time_t(const char *fmt, const time_t *value, char **dest)
 {
     int r = 1;
-    time_t now0;
     struct tm *tm, tmpbuf;
     char *buf;
 
@@ -270,8 +271,7 @@ static int strftime_expand(const char *fmt, char **dest)
     if (!buf)
         return AVERROR(ENOMEM);
 
-    time(&now0);
-    tm = localtime_r(&now0, &tmpbuf);
+    tm = localtime_r(value, &tmpbuf);
     r = strftime(buf, MAX_URL_SIZE, fmt, tm);
     if (!r) {
         av_free(buf);
@@ -282,6 +282,19 @@ static int strftime_expand(const char *fmt, char **dest)
     return r;
 }
 
+static int strftime_expand(const char *fmt, char **dest)
+{
+    time_t now0;
+    time(&now0);
+    return strftime_expand_time_t(fmt, &now0, dest);
+}
+
+static int strftime_expand_prog(const char *fmt, const double prog_date_time, char **dest)
+{
+    time_t value = (time_t)prog_date_time;
+    return strftime_expand_time_t(fmt, &value, dest);
+}
+
 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, const char *filename,
                           AVDictionary **options)
 {
@@ -1721,7 +1734,11 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
             int r;
             char *expanded = NULL;
 
-            r = strftime_expand(vs->basename, &expanded);
+            if (c->use_localtime_prog) {
+                r = strftime_expand_prog(vs->basename, vs->curr_prog_date_time, &expanded);
+            } else {
+                r = strftime_expand(vs->basename, &expanded);
+            }
             if (r < 0) {
                 av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
                 return r;
@@ -2615,6 +2632,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
         if (vs->start_pos || hls->segment_type != SEGMENT_TYPE_FMP4) {
             double cur_duration =  (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
             ret = hls_append_segment(s, hls, vs, cur_duration, vs->start_pos, vs->size);
+            vs->curr_prog_date_time += cur_duration;
             vs->end_pts = pkt->pts;
             vs->duration = 0;
             if (ret < 0) {
@@ -2971,6 +2989,7 @@ static int hls_init(AVFormatContext *s)
         vs->end_pts   = AV_NOPTS_VALUE;
         vs->current_segment_final_filename_fmt[0] = '\0';
         vs->initial_prog_date_time = initial_program_date_time;
+        vs->curr_prog_date_time = initial_program_date_time;
 
         for (j = 0; j < vs->nb_streams; j++) {
             vs->has_video += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
@@ -3038,7 +3057,11 @@ static int hls_init(AVFormatContext *s)
                     int r;
                     char *expanded = NULL;
 
-                    r = strftime_expand(vs->fmp4_init_filename, &expanded);
+                    if (hls->use_localtime_prog) {
+                        r = strftime_expand_prog(vs->fmp4_init_filename, vs->curr_prog_date_time, &expanded);
+                    } else {
+                        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;
@@ -3158,6 +3181,7 @@ static const AVOption options[] = {
     {"iframes_only", "add EXT-X-I-FRAMES-ONLY, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_I_FRAMES_ONLY }, 0, UINT_MAX, E, "flags"},
     {"strftime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
     {"strftime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
+    {"strftime_prog", "set filename expanish with program date time", OFFSET(use_localtime_prog), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
     {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" },
     {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
     {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
-- 
2.39.2 (Apple Git-143)

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message
  2023-10-27  3:59 [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified Dave Johansen
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 2/4] avformat/hlsenc: Add strftime_prog for using PROGRAM-DATE-TIME in the segment filename Dave Johansen
@ 2023-10-27  3:59 ` Dave Johansen
  2023-10-27  7:58   ` Steven Liu
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 4/4] avformat/hlsenc: Add second_level_segment_microsecond for using %%f to specify microseconds of time in segment filename Dave Johansen
  2023-10-27 10:58 ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified epirat07
  3 siblings, 1 reply; 11+ messages in thread
From: Dave Johansen @ 2023-10-27  3:59 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Dave Johansen

---
 libavformat/hlsenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 24a0304f78..93c47b631b 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1013,7 +1013,7 @@ static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls
                                              't',  (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
                 av_log(hls, AV_LOG_ERROR,
                        "Invalid second level segment filename template '%s', "
-                       "you can try to remove second_level_segment_time flag\n",
+                       "you can try to remove second_level_segment_duration flag\n",
                        vs->avf->url);
                 av_freep(&filename);
                 return AVERROR(EINVAL);
@@ -1106,7 +1106,7 @@ static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, V
             char *filename = NULL;
             if (replace_int_data_in_filename(&filename, oc->url, '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",
+                        "you can try to remove second_level_segment_duration flag\n",
                        oc->url);
                 av_freep(&filename);
                 return AVERROR(EINVAL);
-- 
2.39.2 (Apple Git-143)

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [FFmpeg-devel] [PATCH 4/4] avformat/hlsenc: Add second_level_segment_microsecond for using %%f to specify microseconds of time in segment filename
  2023-10-27  3:59 [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified Dave Johansen
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 2/4] avformat/hlsenc: Add strftime_prog for using PROGRAM-DATE-TIME in the segment filename Dave Johansen
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message Dave Johansen
@ 2023-10-27  3:59 ` Dave Johansen
  2023-10-27 10:58 ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified epirat07
  3 siblings, 0 replies; 11+ messages in thread
From: Dave Johansen @ 2023-10-27  3:59 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Dave Johansen

---
 libavformat/hlsenc.c | 51 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 93c47b631b..f613e35984 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -103,6 +103,7 @@ typedef enum HLSFlags {
     HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime  e.g.: %%03d
     HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime  e.g.: %%09t
     HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime  e.g.: %%014s
+    HLS_SECOND_LEVEL_SEGMENT_MICROSECOND = (1 << 15), // include microseconds of localtime in segment filenames when use_localtime  e.g.: %%f
     HLS_TEMP_FILE = (1 << 11),
     HLS_PERIODIC_REKEY = (1 << 12),
     HLS_INDEPENDENT_SEGMENTS = (1 << 13),
@@ -496,7 +497,7 @@ static int replace_str_data_in_filename(char **s, const char *filename, char pla
     return found_count;
 }
 
-static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
+static int replace_int_data_in_filename_forced(char **s, const char *filename, char placeholder, int64_t number, int forced_digits)
 {
     const char *p;
     char c;
@@ -521,6 +522,9 @@ static int replace_int_data_in_filename(char **s, const char *filename, char pla
                 nd = nd * 10 + *(p + addchar_count) - '0';
                 addchar_count++;
             }
+            if (forced_digits > nd) {
+                nd = forced_digits;
+            }
 
             if (*(p + addchar_count) == placeholder) {
                 av_bprintf(&buf, "%0*"PRId64, (number < 0) ? nd : nd++, number);
@@ -544,6 +548,11 @@ static int replace_int_data_in_filename(char **s, const char *filename, char pla
     return found_count;
 }
 
+static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
+{
+    return replace_int_data_in_filename_forced(s, filename, placeholder, number, 0);
+}
+
 static void write_styp(AVIOContext *pb)
 {
     avio_wb32(pb, 24);
@@ -1020,6 +1029,20 @@ static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls
             }
             ff_format_set_url(vs->avf, filename);
         }
+        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_MICROSECOND) {
+            char *filename = NULL;
+            double mod_res;
+            if (replace_int_data_in_filename_forced(&filename, vs->avf->url,
+                                             'f',  1000000 * modf(vs->curr_prog_date_time, &mod_res), 6) < 1) {
+                av_log(hls, AV_LOG_ERROR,
+                       "Invalid second level segment filename template '%s', "
+                       "you can try to remove second_level_segment_microsecond flag\n",
+                       vs->avf->url);
+                av_freep(&filename);
+                return AVERROR(EINVAL);
+            }
+            ff_format_set_url(vs->avf, filename);
+        }
     }
     return 0;
 }
@@ -1043,6 +1066,11 @@ static int sls_flag_check_duration_size_index(HLSContext *hls)
                "second_level_segment_index hls_flag requires strftime to be true\n");
         ret = AVERROR(EINVAL);
     }
+    if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_MICROSECOND) {
+        av_log(hls, AV_LOG_ERROR,
+               "second_level_segment_microsecond hls_flag requires strftime to be true\n");
+        ret = AVERROR(EINVAL);
+    }
 
     return ret;
 }
@@ -1063,12 +1091,17 @@ static int sls_flag_check_duration_size(HLSContext *hls, VariantStream *vs)
                "second_level_segment_size hls_flag works only with file protocol segment names\n");
         ret = AVERROR(EINVAL);
     }
+    if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_MICROSECOND) && !segment_renaming_ok) {
+        av_log(hls, AV_LOG_ERROR,
+               "second_level_segment_microsecond hls_flag works only with file protocol segment names\n");
+        ret = AVERROR(EINVAL);
+    }
 
     return ret;
 }
 
 static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename) {
-    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
+    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION | HLS_SECOND_LEVEL_SEGMENT_MICROSECOND)) &&
         strlen(vs->current_segment_final_filename_fmt)) {
         ff_rename(old_filename, vs->avf->url, hls);
     }
@@ -1088,7 +1121,7 @@ static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, V
         }
         ff_format_set_url(oc, filename);
     }
-    if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
+    if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION | HLS_SECOND_LEVEL_SEGMENT_MICROSECOND)) {
         av_strlcpy(vs->current_segment_final_filename_fmt, oc->url,
                    sizeof(vs->current_segment_final_filename_fmt));
         if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
@@ -1113,6 +1146,17 @@ static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, V
             }
             ff_format_set_url(oc, filename);
         }
+        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_MICROSECOND) {
+            char *filename = NULL;
+            if (replace_int_data_in_filename(&filename, oc->url, 'f', 0) < 1) {
+                av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
+                                        "you can try to remove second_level_segment_microsecond flag\n",
+                       oc->url);
+                av_freep(&filename);
+                return AVERROR(EINVAL);
+            }
+            ff_format_set_url(oc, filename);
+        }
     }
     return 0;
 }
@@ -3176,6 +3220,7 @@ static const AVOption options[] = {
     {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX,   E, "flags"},
+    {"second_level_segment_microsecond", "include microseconds of localtime in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_MICROSECOND }, 0, UINT_MAX,   E, "flags"},
     {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX,   E, "flags"},
     {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
     {"iframes_only", "add EXT-X-I-FRAMES-ONLY, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_I_FRAMES_ONLY }, 0, UINT_MAX, E, "flags"},
-- 
2.39.2 (Apple Git-143)

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message Dave Johansen
@ 2023-10-27  7:58   ` Steven Liu
  0 siblings, 0 replies; 11+ messages in thread
From: Steven Liu @ 2023-10-27  7:58 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Dave Johansen

Dave Johansen <davejohansen@gmail.com> 于2023年10月27日周五 12:00写道:
>
> ---
>  libavformat/hlsenc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index 24a0304f78..93c47b631b 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -1013,7 +1013,7 @@ static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls
>                                               't',  (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
>                  av_log(hls, AV_LOG_ERROR,
>                         "Invalid second level segment filename template '%s', "
> -                       "you can try to remove second_level_segment_time flag\n",
> +                       "you can try to remove second_level_segment_duration flag\n",
>                         vs->avf->url);
>                  av_freep(&filename);
>                  return AVERROR(EINVAL);
> @@ -1106,7 +1106,7 @@ static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, V
>              char *filename = NULL;
>              if (replace_int_data_in_filename(&filename, oc->url, '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",
> +                        "you can try to remove second_level_segment_duration flag\n",
>                         oc->url);
>                  av_freep(&filename);
>                  return AVERROR(EINVAL);
> --
> 2.39.2 (Apple Git-143)
>
> _______________________________________________
> 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".

LGTM
Good catch


Thanks
Steven
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified
  2023-10-27  3:59 [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified Dave Johansen
                   ` (2 preceding siblings ...)
  2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 4/4] avformat/hlsenc: Add second_level_segment_microsecond for using %%f to specify microseconds of time in segment filename Dave Johansen
@ 2023-10-27 10:58 ` epirat07
  2023-10-27 21:28   ` [FFmpeg-devel] [PATCH] avformat/hlsenc: Handle when fractional seconds not set and error out when init_program_date_time can't be parsed Dave Johansen
  2023-10-27 21:32   ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen
  3 siblings, 2 replies; 11+ messages in thread
From: epirat07 @ 2023-10-27 10:58 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On 27 Oct 2023, at 5:59, Dave Johansen wrote:

> ---
>  doc/muxers.texi      |  3 +++
>  libavformat/hlsenc.c | 41 +++++++++++++++++++++++++----------------
>  2 files changed, 28 insertions(+), 16 deletions(-)
>

Thanks for the revised patch!

> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index f6071484ff..87c19a5cb9 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -1086,6 +1086,9 @@ seeking. This flag should be used with the @code{hls_time} option.
>  @item program_date_time
>  Generate @code{EXT-X-PROGRAM-DATE-TIME} tags.
>
> +@item init_program_date_time
> +Time to start program date time at.
> +

Probably would help to mention the expected format here.

>  @item second_level_segment_index
>  Makes it possible to use segment indexes as %%d in hls_segment_filename expression
>  besides date/time values when strftime is on.
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index 4ef84c05c1..5dfff6b2b6 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -212,6 +212,8 @@ typedef struct HLSContext {
>      int64_t recording_time;
>      int64_t max_seg_size; // every segment file max size
>
> +    char *init_program_date_time;
> +
>      char *baseurl;
>      char *vtt_format_options_str;
>      char *subtitle_filename;
> @@ -1192,6 +1194,25 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
>      return 0;
>  }
>
> +static double parse_iso8601(const char *ptr) {
> +    struct tm program_date_time;
> +    int y,M,d,h,m,s;
> +    double ms;
> +    if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) {
> +        return -1;
> +    }
> +
> +    program_date_time.tm_year = y - 1900;
> +    program_date_time.tm_mon = M - 1;
> +    program_date_time.tm_mday = d;
> +    program_date_time.tm_hour = h;
> +    program_date_time.tm_min = m;
> +    program_date_time.tm_sec = s;
> +    program_date_time.tm_isdst = -1;
> +
> +    return mktime(&program_date_time) + (double)(ms / 1000);
> +}
> +
>  static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
>  {
>      HLSContext *hls = s->priv_data;
> @@ -1257,24 +1278,11 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
>                  }
>              }
>          } else if (av_strstart(line, "#EXT-X-PROGRAM-DATE-TIME:", &ptr)) {
> -            struct tm program_date_time;
> -            int y,M,d,h,m,s;
> -            double ms;
> -            if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) {
> +            discont_program_date_time = parse_iso8601(ptr);
> +            if (discont_program_date_time < 0) {
>                  ret = AVERROR_INVALIDDATA;
>                  goto fail;
>              }
> -
> -            program_date_time.tm_year = y - 1900;
> -            program_date_time.tm_mon = M - 1;
> -            program_date_time.tm_mday = d;
> -            program_date_time.tm_hour = h;
> -            program_date_time.tm_min = m;
> -            program_date_time.tm_sec = s;
> -            program_date_time.tm_isdst = -1;
> -
> -            discont_program_date_time = mktime(&program_date_time);
> -            discont_program_date_time += (double)(ms / 1000);
>          } else if (av_strstart(line, "#", NULL)) {
>              continue;
>          } else if (line[0]) {
> @@ -2867,7 +2875,7 @@ static int hls_init(AVFormatContext *s)
>      char *p = NULL;
>      int http_base_proto = ff_is_http_proto(s->url);
>      int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
> -    double initial_program_date_time = av_gettime() / 1000000.0;
> +    double initial_program_date_time = hls->init_program_date_time ? parse_iso8601(hls->init_program_date_time) : av_gettime() / 1000000.0;

As parse_iso8601 parsing user input can fail, it should properly report the error and fail. Especially given that it does not accept all variations
of ISO-8601 date/time IIUC.

It might be confusing if the user specifies a time, forgets the milliseconds and it will just silently not use the option at all?

>
>      if (hls->use_localtime) {
>          pattern = get_default_pattern_localtime_fmt(s);
> @@ -3141,6 +3149,7 @@ static const AVOption options[] = {
>      {"split_by_time", "split the hls segment by time which user set by hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX,   E, "flags"},
>      {"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX,   E, "flags"},
>      {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX,   E, "flags"},
> +    {"init_program_date_time", "Time to start program date time at", OFFSET(init_program_date_time), AV_OPT_TYPE_STRING, .flags = E},
>      {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX,   E, "flags"},
>      {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX,   E, "flags"},
>      {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX,   E, "flags"},
> -- 
> 2.39.2 (Apple Git-143)
>
> _______________________________________________
> 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".
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [FFmpeg-devel] [PATCH] avformat/hlsenc: Handle when fractional seconds not set and error out when init_program_date_time can't be parsed
  2023-10-27 10:58 ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified epirat07
@ 2023-10-27 21:28   ` Dave Johansen
  2023-10-27 21:32   ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen
  1 sibling, 0 replies; 11+ messages in thread
From: Dave Johansen @ 2023-10-27 21:28 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Dave Johansen

---
 libavformat/hlsenc.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index f613e35984..e1714d4eed 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1253,9 +1253,11 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
 
 static double parse_iso8601(const char *ptr) {
     struct tm program_date_time;
-    int y,M,d,h,m,s;
-    double ms;
-    if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) {
+    int y,M,d,h,m;
+    double s;
+    int num_scanned = sscanf(ptr, "%d-%d-%dT%d:%d:%lf", &y, &M, &d, &h, &m, &s);
+
+    if (num_scanned < 6) {
         return -1;
     }
 
@@ -1264,10 +1266,10 @@ static double parse_iso8601(const char *ptr) {
     program_date_time.tm_mday = d;
     program_date_time.tm_hour = h;
     program_date_time.tm_min = m;
-    program_date_time.tm_sec = s;
+    program_date_time.tm_sec = 0;
     program_date_time.tm_isdst = -1;
 
-    return mktime(&program_date_time) + (double)(ms / 1000);
+    return mktime(&program_date_time) + s;
 }
 
 static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
@@ -2937,7 +2939,17 @@ static int hls_init(AVFormatContext *s)
     char *p = NULL;
     int http_base_proto = ff_is_http_proto(s->url);
     int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
-    double initial_program_date_time = hls->init_program_date_time ? parse_iso8601(hls->init_program_date_time) : av_gettime() / 1000000.0;
+    double initial_program_date_time;
+
+    if (hls->init_program_date_time) {
+        initial_program_date_time = parse_iso8601(hls->init_program_date_time);
+        if (initial_program_date_time < 0) {
+            av_log(s, AV_LOG_ERROR, "Invalid init_program_date_time\n");
+            return AVERROR(EINVAL);
+        }
+    } else {
+        initial_program_date_time = av_gettime() / 1000000.0;
+    }
 
     if (hls->use_localtime) {
         pattern = get_default_pattern_localtime_fmt(s);
@@ -3216,7 +3228,7 @@ static const AVOption options[] = {
     {"split_by_time", "split the hls segment by time which user set by hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX,   E, "flags"},
     {"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX,   E, "flags"},
     {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX,   E, "flags"},
-    {"init_program_date_time", "Time to start program date time at", OFFSET(init_program_date_time), AV_OPT_TYPE_STRING, .flags = E},
+    {"init_program_date_time", "Time to start program date time at (must be %Y-%m-%dT%H:%M:%S and timezone is ignored)", OFFSET(init_program_date_time), AV_OPT_TYPE_STRING, .flags = E},
     {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX,   E, "flags"},
     {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX,   E, "flags"},
-- 
2.39.2 (Apple Git-143)

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified
  2023-10-27 10:58 ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified epirat07
  2023-10-27 21:28   ` [FFmpeg-devel] [PATCH] avformat/hlsenc: Handle when fractional seconds not set and error out when init_program_date_time can't be parsed Dave Johansen
@ 2023-10-27 21:32   ` David Johansen
  2023-11-05  8:20     ` Marton Balint
  1 sibling, 1 reply; 11+ messages in thread
From: David Johansen @ 2023-10-27 21:32 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Fri, Oct 27, 2023 at 4:58 AM <epirat07@gmail.com> wrote:

> On 27 Oct 2023, at 5:59, Dave Johansen wrote:
> >  @item second_level_segment_index
> >  Makes it possible to use segment indexes as %%d in hls_segment_filename
> expression
> >  besides date/time values when strftime is on.
> > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> > index 4ef84c05c1..5dfff6b2b6 100644
> > --- a/libavformat/hlsenc.c
> > +++ b/libavformat/hlsenc.c
> > @@ -212,6 +212,8 @@ typedef struct HLSContext {
> >      int64_t recording_time;
> >      int64_t max_seg_size; // every segment file max size
> >
> > +    char *init_program_date_time;
> > +
> >      char *baseurl;
> >      char *vtt_format_options_str;
> >      char *subtitle_filename;
> > @@ -1192,6 +1194,25 @@ static int hls_append_segment(struct
> AVFormatContext *s, HLSContext *hls,
> >      return 0;
> >  }
> >
> > +static double parse_iso8601(const char *ptr) {
> > +    struct tm program_date_time;
> > +    int y,M,d,h,m,s;
> > +    double ms;
> > +    if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s,
> &ms) != 7) {
> > +        return -1;
> > +    }
> > +
> > +    program_date_time.tm_year = y - 1900;
> > +    program_date_time.tm_mon = M - 1;
> > +    program_date_time.tm_mday = d;
> > +    program_date_time.tm_hour = h;
> > +    program_date_time.tm_min = m;
> > +    program_date_time.tm_sec = s;
> > +    program_date_time.tm_isdst = -1;
> > +
> > +    return mktime(&program_date_time) + (double)(ms / 1000);
> > +}
> > +
> >  static int parse_playlist(AVFormatContext *s, const char *url,
> VariantStream *vs)
> >  {
> >      HLSContext *hls = s->priv_data;
> > @@ -1257,24 +1278,11 @@ static int parse_playlist(AVFormatContext *s,
> const char *url, VariantStream *vs
> >                  }
> >              }
> >          } else if (av_strstart(line, "#EXT-X-PROGRAM-DATE-TIME:",
> &ptr)) {
> > -            struct tm program_date_time;
> > -            int y,M,d,h,m,s;
> > -            double ms;
> > -            if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h,
> &m, &s, &ms) != 7) {
> > +            discont_program_date_time = parse_iso8601(ptr);
> > +            if (discont_program_date_time < 0) {
> >                  ret = AVERROR_INVALIDDATA;
> >                  goto fail;
> >              }
> > -
> > -            program_date_time.tm_year = y - 1900;
> > -            program_date_time.tm_mon = M - 1;
> > -            program_date_time.tm_mday = d;
> > -            program_date_time.tm_hour = h;
> > -            program_date_time.tm_min = m;
> > -            program_date_time.tm_sec = s;
> > -            program_date_time.tm_isdst = -1;
> > -
> > -            discont_program_date_time = mktime(&program_date_time);
> > -            discont_program_date_time += (double)(ms / 1000);
> >          } else if (av_strstart(line, "#", NULL)) {
> >              continue;
> >          } else if (line[0]) {
> > @@ -2867,7 +2875,7 @@ static int hls_init(AVFormatContext *s)
> >      char *p = NULL;
> >      int http_base_proto = ff_is_http_proto(s->url);
> >      int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
> > -    double initial_program_date_time = av_gettime() / 1000000.0;
> > +    double initial_program_date_time = hls->init_program_date_time ?
> parse_iso8601(hls->init_program_date_time) : av_gettime() / 1000000.0;
>
> As parse_iso8601 parsing user input can fail, it should properly report
> the error and fail. Especially given that it does not accept all variations
> of ISO-8601 date/time IIUC.
>
> It might be confusing if the user specifies a time, forgets the
> milliseconds and it will just silently not use the option at all?
>

I added improved parsing and error reporting. I sent in the patch, but is
there a way for me to tie it to this patchset in the future?
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified
  2023-10-27 21:32   ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen
@ 2023-11-05  8:20     ` Marton Balint
  2023-11-07  0:31       ` [FFmpeg-devel] [PATCH] Use existing function to parse time Dave Johansen
  2023-11-08 23:45       ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen
  0 siblings, 2 replies; 11+ messages in thread
From: Marton Balint @ 2023-11-05  8:20 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On Fri, 27 Oct 2023, David Johansen wrote:

> On Fri, Oct 27, 2023 at 4:58 AM <epirat07@gmail.com> wrote:
>
>> On 27 Oct 2023, at 5:59, Dave Johansen wrote:
>> >  @item second_level_segment_index
>> >  Makes it possible to use segment indexes as %%d in hls_segment_filename
>> expression
>> >  besides date/time values when strftime is on.
>> > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> > index 4ef84c05c1..5dfff6b2b6 100644
>> > --- a/libavformat/hlsenc.c
>> > +++ b/libavformat/hlsenc.c
>> > @@ -212,6 +212,8 @@ typedef struct HLSContext {
>> >      int64_t recording_time;
>> >      int64_t max_seg_size; // every segment file max size
>> >
>> > +    char *init_program_date_time;
>> > +
>> >      char *baseurl;
>> >      char *vtt_format_options_str;
>> >      char *subtitle_filename;
>> > @@ -1192,6 +1194,25 @@ static int hls_append_segment(struct
>> AVFormatContext *s, HLSContext *hls,
>> >      return 0;
>> >  }
>> >
>> > +static double parse_iso8601(const char *ptr) {

Please use the existing function av_parse_time(). That can more completely 
handle ISO8601 and even more.

Regards,
Marton
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [FFmpeg-devel] [PATCH] Use existing function to parse time
  2023-11-05  8:20     ` Marton Balint
@ 2023-11-07  0:31       ` Dave Johansen
  2023-11-08 23:45       ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen
  1 sibling, 0 replies; 11+ messages in thread
From: Dave Johansen @ 2023-11-07  0:31 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Dave Johansen

---
 libavformat/hlsenc.c | 32 +++++++-------------------------
 1 file changed, 7 insertions(+), 25 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index e1714d4eed..1baefe852f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -35,6 +35,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
 #include "libavutil/log.h"
+#include "libavutil/parseutils.h"
 #include "libavutil/random_seed.h"
 #include "libavutil/time.h"
 #include "libavutil/time_internal.h"
@@ -1251,27 +1252,6 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
     return 0;
 }
 
-static double parse_iso8601(const char *ptr) {
-    struct tm program_date_time;
-    int y,M,d,h,m;
-    double s;
-    int num_scanned = sscanf(ptr, "%d-%d-%dT%d:%d:%lf", &y, &M, &d, &h, &m, &s);
-
-    if (num_scanned < 6) {
-        return -1;
-    }
-
-    program_date_time.tm_year = y - 1900;
-    program_date_time.tm_mon = M - 1;
-    program_date_time.tm_mday = d;
-    program_date_time.tm_hour = h;
-    program_date_time.tm_min = m;
-    program_date_time.tm_sec = 0;
-    program_date_time.tm_isdst = -1;
-
-    return mktime(&program_date_time) + s;
-}
-
 static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
 {
     HLSContext *hls = s->priv_data;
@@ -1281,6 +1261,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
     char line[MAX_URL_SIZE];
     const char *ptr;
     const char *end;
+    int64_t parsed_time;
     double discont_program_date_time = 0;
 
     if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
@@ -1337,11 +1318,11 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
                 }
             }
         } else if (av_strstart(line, "#EXT-X-PROGRAM-DATE-TIME:", &ptr)) {
-            discont_program_date_time = parse_iso8601(ptr);
-            if (discont_program_date_time < 0) {
+            if (av_parse_time(&parsed_time, ptr, 0)) {
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
+            discont_program_date_time = parsed_time / 1000000.0;
         } else if (av_strstart(line, "#", NULL)) {
             continue;
         } else if (line[0]) {
@@ -2933,6 +2914,7 @@ static int hls_init(AVFormatContext *s)
     int i = 0;
     int j = 0;
     HLSContext *hls = s->priv_data;
+    int64_t parsed_time;
     const char *pattern;
     VariantStream *vs = NULL;
     const char *vtt_pattern = hls->flags & HLS_SINGLE_FILE ? ".vtt" : "%d.vtt";
@@ -2942,11 +2924,11 @@ static int hls_init(AVFormatContext *s)
     double initial_program_date_time;
 
     if (hls->init_program_date_time) {
-        initial_program_date_time = parse_iso8601(hls->init_program_date_time);
-        if (initial_program_date_time < 0) {
+        if (av_parse_time(&parsed_time, hls->init_program_date_time, 0)) {
             av_log(s, AV_LOG_ERROR, "Invalid init_program_date_time\n");
             return AVERROR(EINVAL);
         }
+        initial_program_date_time = parsed_time / 1000000.0;
     } else {
         initial_program_date_time = av_gettime() / 1000000.0;
     }
-- 
2.39.2 (Apple Git-143)

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified
  2023-11-05  8:20     ` Marton Balint
  2023-11-07  0:31       ` [FFmpeg-devel] [PATCH] Use existing function to parse time Dave Johansen
@ 2023-11-08 23:45       ` David Johansen
  1 sibling, 0 replies; 11+ messages in thread
From: David Johansen @ 2023-11-08 23:45 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sun, Nov 5, 2023 at 1:21 AM Marton Balint <cus@passwd.hu> wrote:

>
>
> On Fri, 27 Oct 2023, David Johansen wrote:
>
> > On Fri, Oct 27, 2023 at 4:58 AM <epirat07@gmail.com> wrote:
> >
> >> On 27 Oct 2023, at 5:59, Dave Johansen wrote:
> >> >  @item second_level_segment_index
> >> >  Makes it possible to use segment indexes as %%d in
> hls_segment_filename
> >> expression
> >> >  besides date/time values when strftime is on.
> >> > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> >> > index 4ef84c05c1..5dfff6b2b6 100644
> >> > --- a/libavformat/hlsenc.c
> >> > +++ b/libavformat/hlsenc.c
> >> > @@ -212,6 +212,8 @@ typedef struct HLSContext {
> >> >      int64_t recording_time;
> >> >      int64_t max_seg_size; // every segment file max size
> >> >
> >> > +    char *init_program_date_time;
> >> > +
> >> >      char *baseurl;
> >> >      char *vtt_format_options_str;
> >> >      char *subtitle_filename;
> >> > @@ -1192,6 +1194,25 @@ static int hls_append_segment(struct
> >> AVFormatContext *s, HLSContext *hls,
> >> >      return 0;
> >> >  }
> >> >
> >> > +static double parse_iso8601(const char *ptr) {
>
> Please use the existing function av_parse_time(). That can more completely
> handle ISO8601 and even more.
>

I made a patch for this an submitted it with --in-reply-to with the Message
ID from this email, but it doesn't appear that it linked it to the existing
patches I sent. What's the proper way that I should submit follow on
patches like this in the future?
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-11-08 23:45 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-27  3:59 [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified Dave Johansen
2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 2/4] avformat/hlsenc: Add strftime_prog for using PROGRAM-DATE-TIME in the segment filename Dave Johansen
2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message Dave Johansen
2023-10-27  7:58   ` Steven Liu
2023-10-27  3:59 ` [FFmpeg-devel] [PATCH 4/4] avformat/hlsenc: Add second_level_segment_microsecond for using %%f to specify microseconds of time in segment filename Dave Johansen
2023-10-27 10:58 ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified epirat07
2023-10-27 21:28   ` [FFmpeg-devel] [PATCH] avformat/hlsenc: Handle when fractional seconds not set and error out when init_program_date_time can't be parsed Dave Johansen
2023-10-27 21:32   ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen
2023-11-05  8:20     ` Marton Balint
2023-11-07  0:31       ` [FFmpeg-devel] [PATCH] Use existing function to parse time Dave Johansen
2023-11-08 23:45       ` [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified David Johansen

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git