From patchwork Fri Oct 27 01:12:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Johansen X-Patchwork-Id: 44369 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bf16:b0:15d:8365:d4b8 with SMTP id gc22csp1039609pzb; Thu, 26 Oct 2023 18:13:06 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHUMYllZa0NTLbZTal1sUipM2E3FF4l8NxrXmioley8L0yZI03v9CEUcVZMyTHs5bdXcCn9 X-Received: by 2002:a17:907:a03:b0:9bd:7f40:caa5 with SMTP id bb3-20020a1709070a0300b009bd7f40caa5mr915084ejc.77.1698369186782; Thu, 26 Oct 2023 18:13:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698369186; cv=none; d=google.com; s=arc-20160816; b=HcXHJajxuJnnPvT3PEw+9WuzuAvZMAeAiUE1Ekw5ah0JafidNzMkSOaVV0qgRZ3e3d WRRwVZ7VVHKrupBdeHLOazBGMeczN3st0STn3pP6tObkmQqEQQSIx4W2Xte5zhyOE4KD Y5b3DTdZXSWnRfFrHs6AM7+9FnUL63SULgPQwT1IodyKKJ2U4kOVsOnVWg4tKdyLB9Il 1B5hwiDEhwGrtqFK2mYas66gHVk5fr2T9vhpL2sOYKR6NiRzJrrcvDrC0wj0hUqHkNQ+ aXiDjafhWfofRwyv02xJRKFcXM3rifYhfOe9L8WgZW4n4YqXEtgDo+G9kLd2YOZXTzJz Ft7g== 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:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=EdPunq+ZqgVgNDusnZA1mJ0HczwQUWLOg0GNZZL3Lzc=; fh=BNczk7MtTFTHa4uMdKY29AxmcfAa404kNGyDf0xbsP0=; b=Op0jmCGwibkVT7OyG6IhaAO8xBHRkBkTOQ9sOAmPzK+4cPM9Rx+2pfr+mm/0Djljl0 4Zg+FSfCBH/fK2F86udHWFYKBDLk0gsiERST89UFHdFr6pVs9MZcNo2G9Ap9HIMKiwp/ PtEjmw7cuDUT5z5Tqswh9lUlG47+VwlC1f4vTYRVdynkSsF6mVVJxhUgpHnJmGjj5WhY fU05yiLxomKBBMpMqxRmfN63fQjLckUT14G+mjSKGbrPnnlRhoCYCy+Wuihq7wSBsUtc +CyZeiT2+5aDOG3CcgHRBzEeVgGvhSYz+IIzh5Mqv+ypNtl6i/04S2iQ0VHa+BV/BuwR GLnQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=K5jQAZZ2; 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 5-20020a17090600c500b0099cc01fb28csi252440eji.780.2023.10.26.18.12.56; Thu, 26 Oct 2023 18:13:06 -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=K5jQAZZ2; 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 75ABC68CB33; Fri, 27 Oct 2023 04:12:52 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 871C268B1FF for ; Fri, 27 Oct 2023 04:12:45 +0300 (EEST) Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-1ca82f015e4so13514275ad.1 for ; Thu, 26 Oct 2023 18:12:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1698369163; x=1698973963; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=J2YzzzWfR5Dg1h30UqbBgbPBezvP3d9qA5taZMXpPrA=; b=K5jQAZZ2GIoxMEGxpKgin5G3/aOU2l3SRyBVcOrTjIsX4/vtN1NooWkbsd1Wo3hYUb dnh7OkaoKk7Ocsp20vAmmDFFGbtCq/IHrYtOMNRs8G80rZvk4bxw3HYEbWgz3ZpqqU2C x3EM33lsak2vZs1+rEBFv+cWxR7jS/a4JZgxfzRcJgCb0X0ulm2C1hA4ekqWqrpCr8NA T8Cih18XIPIKfJe95YgeYqmcOtg4dhvmANVAhOy+b722t9JO18F0e1qdP21yS4/lhMGn B0MFbCABPGFZEvs3Np24bc2cbsRMtWxDwwTwIjDfiOad8hBXZxqIHCQNIxJN0y3mDnU3 93lQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698369163; x=1698973963; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=J2YzzzWfR5Dg1h30UqbBgbPBezvP3d9qA5taZMXpPrA=; b=iE/vMWzbPWUm6z/LB/yCOSVY2UDp6G9RtH67TTWrTt7TFYhO8/lKIIZB42su3C+OMd +w8JvOD6ld0TIfy/q3iOrN37JPSmPnT0GRlPBa/pCbyrRazwV9vvSWAU+nj90T+a70Jq u1oJuQINNmwlaIkV4p1UtZGJ1H2Ko7PZApOeOdWEC9Si0hfO+tnTgwy0cx67civFKqEz GqFxk6HmzinLOA2l1FMvOyFVEjI8SA5iqjAsObZR+yn6jHG+/o4PnuHRzMxrngzdIYne //BAgqzlY03XorbO4ajgowaDCy7sse8xE34Yh3Kq0yMfOj5qVlrg5dnEPlXTt9lGQ7nS oBQw== X-Gm-Message-State: AOJu0YxjN0Q7dc724OcAgYOQA2uBpAkF5h/hUT1JxNAWe/JqRq+7PsxQ tLtj19ulVScJtRa40ki5iNCX1oHsqBn0qw== X-Received: by 2002:a17:903:1ca:b0:1c9:d6f8:1902 with SMTP id e10-20020a17090301ca00b001c9d6f81902mr1401524plh.15.1698369163083; Thu, 26 Oct 2023 18:12:43 -0700 (PDT) Received: from localhost.localdomain ([2605:a601:a98f:6200:f8bd:26eb:4d2d:1b2b]) by smtp.gmail.com with ESMTPSA id u13-20020a170902e5cd00b001bb97e51ab4sm306616plf.98.2023.10.26.18.12.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 18:12:42 -0700 (PDT) From: Dave Johansen To: ffmpeg-devel@ffmpeg.org Date: Thu, 26 Oct 2023 19:12:06 -0600 Message-Id: <20231027011206.19197-1-davejohansen@gmail.com> X-Mailer: git-send-email 2.39.2 (Apple Git-143) In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] 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: 7rQ4AfOP0ymr --- 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"},