From patchwork Sun Apr 13 08:22:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Machek X-Patchwork-Id: 23178 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 86C85C3213 for ; Sun, 13 Apr 2025 08:22:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 350B268AB5; Sun, 13 Apr 2025 10:22:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ucw.cz header.i=@ucw.cz header.b="qMzubpqe"; dkim-atps=neutral Received: from jabberwock.ucw.cz (jabberwock.ucw.cz [46.255.230.98]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 914FD68A38 for ; Sun, 13 Apr 2025 10:22:18 +0200 (CEST) Received: by jabberwock.ucw.cz (Postfix, from userid 1017) id 58EB71C013F; Sun, 13 Apr 2025 10:22:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucw.cz; s=gen1; t=1744532538; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=jrTEkKh1Zj48gkbYSn8Ajw8g2OFmEZud4PZv+nEpYo0=; b=qMzubpqe1q4UpmaSGkYxfdhHMte7Nr6ApQVAKVNVpi8m2QsUHgD80+57A7Jq60CLHjtcmo GmUCtJGP4LiNV8H1HLv0wcYy1bq01W0VPFet2FxZfoMtzrEX4OX/JROhJjwmPFEgkmrUhM ZcW18qEIiAL1zA6NFxxCR19ytMXkjhQ= Date: Sun, 13 Apr 2025 10:22:17 +0200 From: Pavel Machek To: laurent.pinchart@ideasonboard.com, libcamera-devel@lists.libcamera.org Subject: [PATCH] cam: Implement %x handling Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" With raw files, we have no good place to store the metadata, yet timestamp, width / height and format is useful for further processing. Implement %x so that timestamped frames etc are possible. Signed-off-by: Pavel Machek diff --git a/src/apps/cam/file_sink.cpp b/src/apps/cam/file_sink.cpp index 65794a2f..22cdaaa2 100644 --- a/src/apps/cam/file_sink.cpp +++ b/src/apps/cam/file_sink.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include @@ -116,6 +118,44 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer, filename.replace(pos, 1, ss.str()); } + std::ostringstream result; + for (size_t i = 0; i < filename.size(); ++i) { + if (filename[i] == '%' && i + 1 < filename.size()) { + char specifier = filename[i + 1]; + i++; // Skip specifier character + switch (specifier) { + case 's': + result << std::setw(6) << std::setfill('0') << buffer->metadata().sequence; + break; + case 'w': + result << stream->configuration().size.width; + break; + case 'h': + result << stream->configuration().size.height; + break; + case 'f': + result << stream->configuration().pixelFormat; + break; + case 't': { + auto now = std::chrono::system_clock::now(); + auto micros = std::chrono::duration_cast( + now.time_since_epoch()).count(); + result << micros; + break; + } + case '%': + result << '%' << specifier; + break; + default: + result << "%BAD%"; + } + } else { + result << filename[i]; + } + } + + filename = result.str(); + Image *image = mappedBuffers_[buffer].get(); #ifdef HAVE_TIFF