From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 3D9A64EA3A for ; Sat, 14 Jun 2025 00:59:40 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id EBE4368CDBF; Sat, 14 Jun 2025 03:59:32 +0300 (EEST) Received: from mail-pf1-f180.google.com (mail-pf1-f180.google.com [209.85.210.180]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 1970968CCFB for ; Sat, 14 Jun 2025 03:59:26 +0300 (EEST) Received: by mail-pf1-f180.google.com with SMTP id d2e1a72fcca58-74801bc6dc5so2254501b3a.1 for ; Fri, 13 Jun 2025 17:59:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749862764; x=1750467564; darn=ffmpeg.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :references:in-reply-to:message-id:from:from:to:cc:subject:date :message-id:reply-to; bh=GqT0ZPimo60a6FEy1N03q1nw+hnobBZHNbEa0Es+aY8=; b=TXJ2AZ1bciq0+gCAgeT1Uz+coVDXbOa44XRx0fthCYZrswPIPyb1nNtUlmOK+LsT1M joIasBoTD1+MbDMwQ0J/s55uP78BAOsqxfqbdP6dHDj1ctbdJHHjFGXCoQJWbwvsBHBW 7bFiTWbBP/5Cxm88KtpnMzuQiiQzW9abl9Q7lCkNKo2TAeJTYAXOjj7UfTvmZDZUMfCD Ig4N9038k0/+3l0g3jg9Y+exFRPaKYYBsCw4k5nykKphaCZVnxx5yu4VD/UdXNxnswfw FcZcuHn5MYJZ6l5rruSg3i3idUaxVC5CEtO/We9Q+6cVBNGj+0Va5xpeWp7LrfZEifTk w4mQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749862764; x=1750467564; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :references:in-reply-to:message-id:from:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=GqT0ZPimo60a6FEy1N03q1nw+hnobBZHNbEa0Es+aY8=; b=D2hiYnCq6AETmGCBUqWdO4/TOJ6g1kVHNgdN2zTgRGb1JWM770bvvTM6NJ6XuyMdR4 NAhvJqfMHqPZsKdpCE4DdiaN4Si8vjIsejv97jnMiECZSsZcMFtq/uaLinAHNUoL1AEG Gdm25nCLxcARU0pDw+hW0TtC+klZ1h/mkAmZNf3IAQtyJ3o4Vt7s5RrAL3OhdwUsT1mp qKOV2qK7SGkgbrC2tKz1A4sVf5/QVwjynkqW62rZ4qer2YJWPOKgxHgbterItzzenFij LgBsx7ivjAFfUHmfGh65kUBfZ+sirFlnTseDjIRQnFngrl/8HVgKBEThLSLQS5D/OfI0 5VKQ== X-Gm-Message-State: AOJu0Yx+WCWG1CqIkUu1Ry/lasG/gwW+UW5frNZhajWllbJ6rYY61ZA3 WbdqI6E1NfbapS7F+yffoWDWL2qKhBRuKLGZwd0yEUZegnFTCZvraK/VuXl1qA== X-Gm-Gg: ASbGncvgETIvy6JdO68EPaAlDTgOySS0YZ6Cdv/TPBQEWD0jjb/6wxFtCqt39xUJEJ9 tx1Xf0QjuqCVQxRdhKLBfjcWP12XBIJh55eLC0x0qORO+mD53NY/6SZ86iahbcFstraB7LnsSZ5 P3VC/Swptt51Xt9KehJux1N6ZIMTZhU091nitevPPhjbR0mk+xGqXx2ORRMsOe61dGn9hpTjebD a1leBh/mTgiI9UiuQIkuNyUW6jln+doj5rXkV4vYYa088+c8l4piKG0fbN+7rOfQJW/6/FesqbL QziP2FdDNGa/w/XvnPlTZO5fdHeNt8gEgEx51dNZAIo5QG6gtkislMDY5/0ZnPAeQKKfqwgzBwd pV5Xc X-Google-Smtp-Source: AGHT+IE2xzTu6aaHdf0U1kLQI2VISAfpkHZ1/rmsffxHJxMh42uQbi/PzLgSnnpBc5T/Z8+1EYU2TQ== X-Received: by 2002:a05:6a00:4b01:b0:736:9f2e:1357 with SMTP id d2e1a72fcca58-7489c483195mr2217511b3a.12.1749862764327; Fri, 13 Jun 2025 17:59:24 -0700 (PDT) Received: from [127.0.0.1] (master.gitmailbox.com. [34.83.118.50]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-748900b37ddsm2363503b3a.134.2025.06.13.17.59.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Jun 2025 17:59:24 -0700 (PDT) From: softworkz X-Google-Original-From: softworkz Message-Id: <79b4f635738e7cb272d05a33093e7cdd24453c85.1749862752.git.ffmpegagent@gmail.com> In-Reply-To: References: Date: Sat, 14 Jun 2025 00:59:07 +0000 Fcc: Sent MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH v2 1/6] avformat/segment: Add segment_write_temp option 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: softworkz Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: From: softworkz Allows to write segments as temp files (.tmp) which are renamed on completion. Signed-off-by: softworkz --- doc/muxers.texi | 5 +++++ libavformat/segment.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 30c95c3d34..6d5c17b4cc 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -3505,6 +3505,11 @@ argument must be a time duration specification, and defaults to 0. If enabled, write an empty segment if there are no packets during the period a segment would usually span. Otherwise, the segment will be filled with the next packet written. Defaults to @code{0}. + +@item segment_write_temp @var{1|0} +Write segments to files with a .tmp extension. Each file is renamed to its +actual name on completion. This can help to prevent segment files from +being accessed before they are complete. Disabled by default (@code{0}). @end table Make sure to require a closed GOP when encoding and to set the GOP diff --git a/libavformat/segment.c b/libavformat/segment.c index 65323ec678..14eba90292 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -121,6 +121,7 @@ typedef struct SegmentContext { int break_non_keyframes; int write_empty; + int segment_write_temp; ///< write segments as temp files and rename on completion int use_rename; char temp_list_filename[1024]; @@ -226,6 +227,14 @@ static int set_segment_filename(AVFormatContext *s) seg->entry_prefix ? seg->entry_prefix : "", av_basename(oc->url)); + // Write segment as a temp file and rename on completion + if(seg->segment_write_temp) { + char *temp_name = av_asprintf("%s%s", buf, ".tmp"); + if (!temp_name) + return AVERROR(ENOMEM); + ff_format_set_url(oc, temp_name); + } + return 0; } @@ -372,7 +381,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) SegmentListEntry *entry = av_mallocz(sizeof(*entry)); if (!entry) { ret = AVERROR(ENOMEM); - goto end; + goto fail; } /* append new element */ @@ -393,7 +402,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) } if ((ret = segment_list_open(s)) < 0) - goto end; + goto fail; for (entry = seg->segment_list_entries; entry; entry = entry->next) segment_list_print_entry(seg->list_pb, seg->list_type, entry, s); if (seg->list_type == LIST_TYPE_M3U8 && is_last) @@ -450,7 +459,20 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) } } -end: + ff_format_io_close(oc, &oc->pb); + + // Now rename the .tmp file to its actual name. + if (seg->segment_write_temp) { + char *final_filename = av_strndup(oc->url, strlen(oc->url) - 4); + if (!final_filename) + return AVERROR(ENOMEM); + ret = ff_rename(oc->url, final_filename, s); + av_free(final_filename); + } + + return ret; + +fail: ff_format_io_close(oc, &oc->pb); return ret; @@ -1075,6 +1097,7 @@ static const AVOption options[] = { { "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E }, { "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, + { "segment_write_temp", "write segments as temp files (.tmp) and rename on completion", OFFSET(segment_write_temp), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, { NULL }, }; -- ffmpeg-codebot _______________________________________________ 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".