[FFmpeg-devel] [PATCH] Add init_program_date_time so start time can be specified

2023-10-17 Thread Dave Johansen
---
 doc/muxers.texi  | 3 +++
 libavformat/hlsenc.c | 7 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

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..474322cc21 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -28,6 +28,8 @@
 #include 
 #endif
 
+#include "float.h"
+
 #include "libavutil/avassert.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/avstring.h"
@@ -212,6 +214,8 @@ typedef struct HLSContext {
 int64_t recording_time;
 int64_t max_seg_size; // every segment file max size
 
+double init_program_date_time;
+
 char *baseurl;
 char *vtt_format_options_str;
 char *subtitle_filename;
@@ -2867,7 +2871,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() / 100.0;
+double initial_program_date_time = hls->init_program_date_time ? 
hls->init_program_date_time : av_gettime() / 100.0;
 
 if (hls->use_localtime) {
 pattern = get_default_pattern_localtime_fmt(s);
@@ -3141,6 +3145,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_DOUBLE, {.dbl = 0 }, 0, DBL_MAX,   
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] Add init_program_date_time so start time can be specified

2023-10-26 Thread 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() / 100.0;
+double initial_program_date_time = hls->init_program_date_time ? 
parse_iso8601(hls->init_program_date_time) : av_gettime() / 100.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, vi

[FFmpeg-devel] [PATCH] avformat/hlsenc: Add CHANNELS to EXT-X-MEDIA for Audio

2023-10-26 Thread Dave Johansen
---
 libavformat/dashenc.c | 3 ++-
 libavformat/hlsenc.c  | 8 +++-
 libavformat/hlsplaylist.c | 5 -
 libavformat/hlsplaylist.h | 2 +-
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 96f4a5fbdf..15f700acbc 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1284,7 +1284,8 @@ static int write_manifest(AVFormatContext *s, int final)
 continue;
 get_hls_playlist_name(playlist_file, sizeof(playlist_file), 
NULL, i);
 ff_hls_write_audio_rendition(c->m3u8_out, audio_group,
- playlist_file, NULL, i, 
is_default);
+ playlist_file, NULL, i, 
is_default,
+ 
s->streams[i]->codecpar->ch_layout.nb_channels);
 max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
   os->muxer_overhead, 
max_audio_bitrate);
 if (!av_strnstr(audio_codec_str, os->codec_str, 
sizeof(audio_codec_str))) {
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 4ef84c05c1..7dfb8d0a9f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1386,6 +1386,7 @@ static int create_master_playlist(AVFormatContext *s,
 int is_file_proto = proto && !strcmp(proto, "file");
 int use_temp_file = is_file_proto && ((hls->flags & HLS_TEMP_FILE) || 
hls->master_publish_rate);
 char temp_filename[MAX_URL_SIZE];
+int nb_channels;
 
 input_vs->m3u8_created = 1;
 if (!hls->master_m3u8_created) {
@@ -1434,8 +1435,13 @@ static int create_master_playlist(AVFormatContext *s,
 av_log(s, AV_LOG_ERROR, "Unable to find relative URL\n");
 goto fail;
 }
+nb_channels = 0;
+for (j = 0; j < vs->nb_streams; j++)
+if (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
+if (vs->streams[j]->codecpar->ch_layout.nb_channels > 
nb_channels)
+nb_channels = 
vs->streams[j]->codecpar->ch_layout.nb_channels;
 
-ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, 
vs->language, i, hls->has_default_key ? vs->is_default : 1);
+ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, 
vs->language, i, hls->has_default_key ? vs->is_default : 1, nb_channels);
 }
 
 /* For variant streams with video add #EXT-X-STREAM-INF tag with 
attributes*/
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index 2bf05f3c7c..4f35d0388f 100644
--- a/libavformat/hlsplaylist.c
+++ b/libavformat/hlsplaylist.c
@@ -39,7 +39,7 @@ void ff_hls_write_playlist_version(AVIOContext *out, int 
version)
 
 void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup,
   const char *filename, const char *language,
-  int name_id, int is_default)
+  int name_id, int is_default, int nb_channels)
 {
 if (!out || !agroup || !filename)
 return;
@@ -49,6 +49,9 @@ void ff_hls_write_audio_rendition(AVIOContext *out, const 
char *agroup,
 if (language) {
 avio_printf(out, "LANGUAGE=\"%s\",", language);
 }
+if (nb_channels) {
+avio_printf(out, "CHANNELS=\"%d\",", nb_channels);
+}
 avio_printf(out, "URI=\"%s\"\n", filename);
 }
 
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index 1928fe787d..c2744c227c 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -38,7 +38,7 @@ typedef enum {
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
 void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup,
   const char *filename, const char *language,
-  int name_id, int is_default);
+  int name_id, int is_default, int 
nb_channels);
 void ff_hls_write_subtitle_rendition(AVIOContext *out, const char *sgroup,
  const char *filename, const char 
*language,
  int name_id, int is_default);
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified

2023-10-26 Thread 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() / 100.0;
+double initial_program_date_time = hls->init_program_date_time ? 
parse_iso8601(hls->init_program_date_time) : av_gettime() / 100.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, vi

[FFmpeg-devel] [PATCH 2/4] avformat/hlsenc: Add strftime_prog for using PROGRAM-DATE-TIME in the segment filename

2023-10-26 Thread 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

[FFmpeg-devel] [PATCH 3/4] avformat/hlsenc: Fix name of flag in error message

2023-10-26 Thread 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-requ...@ffmpeg.org with subject "unsubscribe".


[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-26 Thread 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',  100 * 
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_MICROS

[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 Thread 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() / 100.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() / 100.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avformat/hlsenc: Move lrint outside of loop

2023-10-27 Thread Dave Johansen
---
 libavformat/hlsenc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 4ef84c05c1..e59a38b497 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1538,7 +1538,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 {
 HLSContext *hls = s->priv_data;
 HLSSegment *en;
-int target_duration = 0;
+double target_duration = 0;
 int ret = 0;
 char temp_filename[MAX_URL_SIZE];
 char temp_vtt_filename[MAX_URL_SIZE];
@@ -1589,12 +1589,12 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 
 for (en = vs->segments; en; en = en->next) {
 if (target_duration <= en->duration)
-target_duration = lrint(en->duration);
+target_duration = en->duration;
 }
 
 vs->discontinuity_set = 0;
 ff_hls_write_playlist_header(byterange_mode ? hls->m3u8_out : vs->out, 
hls->version, hls->allowcache,
- target_duration, sequence, hls->pl_type, 
hls->flags & HLS_I_FRAMES_ONLY);
+ lrint(target_duration), sequence, 
hls->pl_type, hls->flags & HLS_I_FRAMES_ONLY);
 
 if ((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && 
vs->discontinuity_set==0) {
 avio_printf(byterange_mode ? hls->m3u8_out : vs->out, 
"#EXT-X-DISCONTINUITY\n");
@@ -1643,7 +1643,7 @@ static int hls_window(AVFormatContext *s, int last, 
VariantStream *vs)
 goto fail;
 }
 ff_hls_write_playlist_header(hls->sub_m3u8_out, hls->version, 
hls->allowcache,
- target_duration, sequence, 
PLAYLIST_TYPE_NONE, 0);
+ lrint(target_duration), sequence, 
PLAYLIST_TYPE_NONE, 0);
 for (en = vs->segments; en; en = en->next) {
 ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
   en->duration, 0, en->size, en->pos,
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avformat/hlsenc: Only append postfix to fmp4 init filename if not in the subdir

2023-11-02 Thread Dave Johansen
---
 libavformat/hlsenc.c | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 4ef84c05c1..dd1a461cce 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1931,6 +1931,30 @@ fail:
 return ret;
 }
 
+static int validate_subdir(const char *fn)
+{
+const char *subdir_name;
+char *fn_dup = NULL;
+int ret = 0;
+
+if (!fn)
+return AVERROR(EINVAL);
+
+fn_dup = av_strdup(fn);
+if (!fn_dup)
+return AVERROR(ENOMEM);
+subdir_name = av_dirname(fn_dup);
+
+if (!av_stristr(subdir_name, "%v")) {
+ret = AVERROR(EINVAL);
+goto fail;
+}
+
+fail:
+av_freep(&fn_dup);
+return ret;
+}
+
 static int format_name(const char *buf, char **s, int index, const char 
*varname)
 {
 const char *proto, *dir;
@@ -3019,7 +3043,7 @@ static int hls_init(AVFormatContext *s)
 av_freep(&vs->fmp4_init_filename);
 ret = format_name(hls->fmp4_init_filename,
   &vs->fmp4_init_filename, i, 
vs->varname);
-} else {
+} else if (validate_subdir(s->url) < 0) {
 ret = append_postfix(vs->fmp4_init_filename, 
fmp4_init_filename_len, i);
 }
 if (ret < 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avformat/hlsenc: Allow setting master_pl_publish_rate to a negative value to have it write immediately

2023-11-03 Thread Dave Johansen
---
 libavformat/hlsenc.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 4ef84c05c1..76d8094de6 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -245,7 +245,7 @@ typedef struct HLSContext {
 char *var_stream_map; /* user specified variant stream map string */
 char *cc_stream_map; /* user specified closed caption streams map string */
 char *master_pl_name;
-unsigned int master_publish_rate;
+int master_publish_rate;
 int http_persistent;
 AVIOContext *m3u8_out;
 AVIOContext *sub_m3u8_out;
@@ -1388,7 +1388,9 @@ static int create_master_playlist(AVFormatContext *s,
 char temp_filename[MAX_URL_SIZE];
 
 input_vs->m3u8_created = 1;
-if (!hls->master_m3u8_created) {
+if (hls->master_publish_rate < 0) {
+hls->master_publish_rate = 0;
+} else if (!hls->master_m3u8_created) {
 /* For the first time, wait until all the media playlists are created 
*/
 for (i = 0; i < hls->nb_varstreams; i++)
 if (!hls->var_streams[i].m3u8_created)
@@ -3162,7 +3164,7 @@ static const AVOption options[] = {
 {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), 
AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,E},
 {"cc_stream_map", "Closed captions stream map string", 
OFFSET(cc_stream_map), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,E},
 {"master_pl_name", "Create HLS master playlist with this name", 
OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,E},
-{"master_pl_publish_rate", "Publish master play list every after this many 
segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 
0, UINT_MAX, E},
+{"master_pl_publish_rate", "Publish master play list every after this many 
segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 
INT_MIN, INT_MAX, E},
 {"http_persistent", "Use persistent HTTP connections", 
OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
 {"timeout", "set timeout for socket I/O operations", OFFSET(timeout), 
AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
 {"ignore_io_errors", "Ignore IO errors for stable long-duration runs with 
network output", OFFSET(ignore_io_errors), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 
1, E },
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] Use existing function to parse time

2023-11-06 Thread 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 / 100.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 / 100.0;
 } else {
 initial_program_date_time = av_gettime() / 100.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avformat/hlsenc: Only prevent init_time from being used when splitting by time

2023-11-06 Thread Dave Johansen
---
 libavformat/hlsenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 4ef84c05c1..3548299770 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -3090,7 +3090,7 @@ static int hls_init(AVFormatContext *s)
 if (hls->flags & HLS_APPEND_LIST) {
 parse_playlist(s, vs->m3u8_name, vs);
 vs->discontinuity = 1;
-if (hls->init_time > 0) {
+if ((hls->flags & HLS_SPLIT_BY_TIME) && (hls->init_time > 0)) {
 av_log(s, AV_LOG_WARNING, "append_list mode does not support 
hls_init_time,"
" hls_init_time value will have no effect\n");
 hls->init_time = 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-requ...@ffmpeg.org with subject "unsubscribe".