[PATCH] cam: Implement %x handling

Barnabás Pőcze barnabas.pocze at ideasonboard.com
Fri May 9 12:44:03 CEST 2025


Hi

2025. 04. 13. 10:22 keltezéssel, Pavel Machek írta:
> 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 <pavel at ucw.cz>
> 
> 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 <string.h>
>   #include <unistd.h>
>   #include <utility>
> +#include <chrono>
> +#include <ctime>
>   
>   #include <libcamera/camera.h>
>   
> @@ -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<std::chrono::microseconds>(
> +					now.time_since_epoch()).count();
> +				result << micros;
> +				break;
> +			}
> +			case '%':
> +				result << '%' << specifier;
> +				break;
> +			default:
> +				result << "%BAD%";

I believe when an unknown specifier is encountered, it should be left as is;
or if `setFilePattern()` has been extended to check the format string, then
it could potentially abort.


Regards,
Barnabás Pőcze


> +			}
> +		} else {
> +			result << filename[i];
> +		}
> +	}
> +	
> +	filename =  result.str();
> +	
>   	Image *image = mappedBuffers_[buffer].get();
>   
>   #ifdef HAVE_TIFF
> 



More information about the libcamera-devel mailing list