[libcamera-devel] [PATCH v2 3/4] cam: Extend request completion handler to deal with multiple streams
Kieran Bingham
kieran.bingham at ideasonboard.com
Wed Apr 3 06:24:27 CEST 2019
Hi Niklas,
On 03/04/2019 02:12, Niklas Söderlund wrote:
> The completion handler needs to handle all buffers in the request. Solve
> this by iterating over all buffers in the completed request and assign
> each stream a name as we encounter them. The buffer writer needs to be
> extended to learn about stream names so it can prefix the files it
> writes with it.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> src/cam/buffer_writer.cpp | 5 +++--
> src/cam/buffer_writer.h | 2 +-
> src/cam/main.cpp | 42 ++++++++++++++++++++++++++++-----------
> 3 files changed, 34 insertions(+), 15 deletions(-)
>
> diff --git a/src/cam/buffer_writer.cpp b/src/cam/buffer_writer.cpp
> index 2d2258b4cd1cbbc2..b82ffaded688226a 100644
> --- a/src/cam/buffer_writer.cpp
> +++ b/src/cam/buffer_writer.cpp
> @@ -19,13 +19,14 @@ BufferWriter::BufferWriter(const std::string &pattern)
> {
> }
>
> -int BufferWriter::write(libcamera::Buffer *buffer)
> +int BufferWriter::write(libcamera::Buffer *buffer,
> + const std::string &streamName)
> {
> std::string filename;
> size_t pos;
> int fd, ret = 0;
>
> - filename = pattern_;
> + filename = streamName + "-" + pattern_;
> pos = filename.find_first_of('#');
> if (pos != std::string::npos) {
> std::stringstream ss;
> diff --git a/src/cam/buffer_writer.h b/src/cam/buffer_writer.h
> index 9705773e0e397d45..7bf785d1e83235ff 100644
> --- a/src/cam/buffer_writer.h
> +++ b/src/cam/buffer_writer.h
> @@ -16,7 +16,7 @@ class BufferWriter
> public:
> BufferWriter(const std::string &pattern = "frame-#.bin");
>
> - int write(libcamera::Buffer *buffer);
> + int write(libcamera::Buffer *buffer, const std::string &streamName);
>
> private:
> std::string pattern_;
> diff --git a/src/cam/main.cpp b/src/cam/main.cpp
> index b47bda21cbb7f220..9af7907a3d937c28 100644
> --- a/src/cam/main.cpp
> +++ b/src/cam/main.cpp
> @@ -145,28 +145,46 @@ static int prepareCameraConfig(std::map<Stream *, StreamConfiguration> *config)
> return 0;
> }
>
> +static std::string streamToName(const Stream *stream)
> +{
> + static std::map<const Stream *, std::string> names;
> +
> + if (names.find(stream) == names.end())
> + names[stream] = std::string("stream") + std::to_string(names.size());
> +
> + return names[stream];
> +}
> +
> static void requestComplete(Request *request, const std::map<Stream *, Buffer *> &buffers)
> {
> static uint64_t last = 0;
> + double fps = 0.0;
>
> if (request->status() == Request::RequestCancelled)
> return;
>
> - Buffer *buffer = buffers.begin()->second;
> + for (auto it = buffers.begin(); it != buffers.end(); ++it) {
> + Stream *stream = it->first;
> + Buffer *buffer = it->second;
> + std::string name = streamToName(stream);
>
> - double fps = buffer->timestamp() - last;
> - fps = last && fps ? 1000000000.0 / fps : 0.0;
> - last = buffer->timestamp();
> + if (it == buffers.begin()) {
> + fps = buffer->timestamp() - last;
> + fps = last && fps ? 1000000000.0 / fps : 0.0;
> + last = buffer->timestamp();
> + }
Should we track FPS on a per stream basis? Here you are really
calculating Requests (with at least one buffer) per second, which might
be a perfectly reasonable thing to calculate, but what if (as a simple
extreme) I queued up requests to alternate between two streams A and B.
--------
R:1 A
R:2 B
R:3 A
R:4 B
--------
Is that 4 frames per interval? or two?
It might be worth splitting the calculation out to a function and
storing the result on a per stream basis without using static locals.
>
> - std::cout << "seq: " << std::setw(6) << std::setfill('0') << buffer->sequence()
> - << " buf: " << buffer->index()
> - << " bytesused: " << buffer->bytesused()
> - << " timestamp: " << buffer->timestamp()
> - << " fps: " << std::fixed << std::setprecision(2) << fps
> - << std::endl;
> + std::cout << name << " seq: " << std::setw(6)
> + << std::setfill('0') << buffer->sequence()
> + << " buf: " << buffer->index()
> + << " bytesused: " << buffer->bytesused()
> + << " timestamp: " << buffer->timestamp()
> + << " fps: " << std::fixed << std::setprecision(2) << fps
> + << std::endl;
>
> - if (writer)
> - writer->write(buffer);
> + if (writer)
> + writer->write(buffer, name);
> + }
>
> request = camera->createRequest();
> if (!request) {
>
--
Regards
--
Kieran
More information about the libcamera-devel
mailing list