From patchwork Fri Oct 27 03:59:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Johansen X-Patchwork-Id: 44372 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bf16:b0:15d:8365:d4b8 with SMTP id gc22csp1102974pzb; Thu, 26 Oct 2023 21:00:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEX35+T0xvEw96KKI/CNoVENX2+uOshNmYCOlbxfqENNONfiI1CpPh1+hrcPvdoxsPlrmNN X-Received: by 2002:a17:907:98a:b0:9c5:2806:72e2 with SMTP id bf10-20020a170907098a00b009c5280672e2mr1527013ejc.34.1698379201422; Thu, 26 Oct 2023 21:00:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698379201; cv=none; d=google.com; s=arc-20160816; b=Q2KW0NjtBaKbEYhOOcv4/xVjv+zWE5pPwCdRSEVVVN/3Y/xkWUugassnwXY0MmNybh y3SZ3/QHs4UrtGl8NEI/26sbfazxcgDZvVXN3T1nvkpvsqXbfEhP2EXI6788qI+SSOa/ Ag/fJbQQk22lQyx+1XGEpYfjGgMsVh3s1RNoruUTCI9OV/1HCuvibyvnjCwy01/IKk4e pAfyjkCVborxB5bo02fH8xvVbCElktiKcQlf32Syv3I6A/GTvi6TZ1QB3fkjGSH9L9xg P+CxEYcj5tl4nvB+F71zyxcJyt+/Th7/G7NILtPP66Gdv+HihoyKsGQXRcnb0ksX90SA Jxag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=EdPunq+ZqgVgNDusnZA1mJ0HczwQUWLOg0GNZZL3Lzc=; fh=BNczk7MtTFTHa4uMdKY29AxmcfAa404kNGyDf0xbsP0=; b=ZjkXnoe9jEF64WR+4wt0fzmR/e/8F/eFz2HpP+QUPmgHlm+hFJlUFQ6pL5yTgyWWk3 MkoS5jdKRYoAcPa8lDwY92XcZMAX01DhhE8SCgnuYWV4gvruRLGURv+JvT47+6frUPhw dZAW9yJ7MnyWPFOnpHur3iHdu4bDmJ739Yy0ednhilnySzHgh72pB20P6veD+i+ySz59 cAXxeSre82S4AgEmehhX4/03vp889lRCSwG2KmpOP2Pnvf78aM7jmiuRqheAiaIHvkK0 KmVRjLnKldt6Vg/lAPkwSFwSQVesv0MLBROkCUI9h67tYEhjvpGIdUQDwcssrK6VwFdO Sw+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b="dXB/EfQQ"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id lg15-20020a170906f88f00b009a18355fefbsi365211ejb.925.2023.10.26.21.00.00; Thu, 26 Oct 2023 21:00:01 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b="dXB/EfQQ"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 077BB68CBD0; Fri, 27 Oct 2023 06:59:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oo1-f54.google.com (mail-oo1-f54.google.com [209.85.161.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F411768CB03 for ; Fri, 27 Oct 2023 06:59:51 +0300 (EEST) Received: by mail-oo1-f54.google.com with SMTP id 006d021491bc7-57d086365f7so980618eaf.0 for ; Thu, 26 Oct 2023 20:59:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1698379189; x=1698983989; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=J2YzzzWfR5Dg1h30UqbBgbPBezvP3d9qA5taZMXpPrA=; b=dXB/EfQQ3g+Ky69nhqkdpASLovXrUZHTRqWgUOGZB8eUy+tBY4rw7x6qK4XfKLueXK NDda13XwyppICi3PJNF8nmpaY+MFy6BzEsdXheBucTNlulJZK/KKb9UHNshjU8q5Ik9f WxgL4DEcGkAS2V3LG3cwJxXB65H5s2D/uJmf/ilUd0cB0JUK3OS1EL0NiP4BAS58kQP+ l8ggyJQ5WjP1hBZCKFQpbgon1hWGxTqNnVnwPUgzoTqp7tAzvdUSZKXsT2EMjt7zTvfU ZlUyKOj4Z/OW6vksIYf2BtDCHvEeiO7nub2timjbc/26WgqzCEVGAOhtEnT6jgiqZbqp VekA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698379189; x=1698983989; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=J2YzzzWfR5Dg1h30UqbBgbPBezvP3d9qA5taZMXpPrA=; b=gpfc+kyEqx7Its3co2ZlwX9gjbUJqh85d0ETXUKqcj5OQ+wNaj8/70J1gXdyG56G9D JPPMGdNRIzD7a8Dzo2A6ehqnDs34o3/j0rBWXQ3zGd5u3kmD+QZZoQBftf6oqxLEZ118 SFViJ54nz++3aaXtolEU48kcBHc2ioYJ2eL7xwq7oE9fECG/Ysy3w72hzjqcHFFmR4zw cVgj3NMiND7jEHTurEh0flCYzKUpLEneMmXNEUT7E07MJhoC+GXz7nCggxq+wX6BDBiH MGfECAQ7ZUzSuT6KmS35qZ27jbrJeMazVkEowSvgGZLSkvM3F31VjwkDEfXx6zgM9ryH KK3g== X-Gm-Message-State: AOJu0Yxwozfxq34K/N2I7XtG37iWR7FjH63LllnNnPh9ET0q2j47NLVM uW90olAFYMopjf/noQFUOTgWUpf2rrT4yQ== X-Received: by 2002:a05:6358:881f:b0:168:ea15:f193 with SMTP id hv31-20020a056358881f00b00168ea15f193mr2074246rwb.23.1698379189422; Thu, 26 Oct 2023 20:59:49 -0700 (PDT) Received: from localhost.localdomain ([2605:a601:a98f:6200:f8bd:26eb:4d2d:1b2b]) by smtp.gmail.com with ESMTPSA id ey22-20020a056a0038d600b0069302c3c050sm364489pfb.218.2023.10.26.20.59.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 20:59:48 -0700 (PDT) From: Dave Johansen To: ffmpeg-devel@ffmpeg.org Date: Thu, 26 Oct 2023 21:59:38 -0600 Message-Id: <20231027035941.23491-1-davejohansen@gmail.com> X-Mailer: git-send-email 2.39.2 (Apple Git-143) MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/4] avformat/hlsenc: Add init_program_date_time so start time can be specified X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Dave Johansen Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: nsPlqwmjYO2Z --- 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"},