summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-09-06 01:35:22 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-09-07 19:18:51 +0300
commita13676f2bb9a86ced75ed640f571512cf1a76afe (patch)
treeda0bfea97abec2b03c4feca663dd1f0304230055
parent013084310836519b57883176d65fb5e9f6c00f8d (diff)
qcam: Use Image class to access pixel data
Replace the manual implementation of frame buffer mapping with the Image class to improve code sharing. The ViewFinder API is updated to take an Image pointer in the render() function to prepare for multi-planar buffer support. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
-rw-r--r--src/qcam/main_window.cpp31
-rw-r--r--src/qcam/main_window.h4
-rw-r--r--src/qcam/meson.build1
-rw-r--r--src/qcam/viewfinder.h6
-rw-r--r--src/qcam/viewfinder_gl.cpp7
-rw-r--r--src/qcam/viewfinder_gl.h2
-rw-r--r--src/qcam/viewfinder_qt.cpp6
-rw-r--r--src/qcam/viewfinder_qt.h2
8 files changed, 23 insertions, 36 deletions
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 129aeb0b..b933ab21 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -7,10 +7,9 @@
#include "main_window.h"
+#include <assert.h>
#include <iomanip>
#include <string>
-#include <sys/mman.h>
-#include <unistd.h>
#include <QComboBox>
#include <QCoreApplication>
@@ -29,6 +28,7 @@
#include <libcamera/camera_manager.h>
#include <libcamera/version.h>
+#include "../cam/image.h"
#include "dng_writer.h"
#ifndef QT_NO_OPENGL
#include "viewfinder_gl.h"
@@ -473,15 +473,10 @@ int MainWindow::startCapture()
for (const std::unique_ptr<FrameBuffer> &buffer : allocator_->buffers(stream)) {
/* Map memory buffers and cache the mappings. */
- const FrameBuffer::Plane &plane = buffer->planes().front();
- size_t length = lseek(plane.fd.fd(), 0, SEEK_END);
- void *memory = mmap(NULL, length, PROT_READ, MAP_SHARED,
- plane.fd.fd(), 0);
-
- mappedBuffers_[buffer.get()] = { static_cast<uint8_t *>(memory),
- plane.length };
- planeData_[buffer.get()] = { static_cast<uint8_t *>(memory) + plane.offset,
- plane.length };
+ std::unique_ptr<Image> image =
+ Image::fromFrameBuffer(buffer.get(), Image::MapMode::ReadOnly);
+ assert(image != nullptr);
+ mappedBuffers_[buffer.get()] = std::move(image);
/* Store buffers on the free list. */
freeBuffers_[stream].enqueue(buffer.get());
@@ -543,12 +538,7 @@ error_disconnect:
error:
requests_.clear();
- for (auto &iter : mappedBuffers_) {
- const Span<uint8_t> &buffer = iter.second;
- munmap(buffer.data(), buffer.size());
- }
mappedBuffers_.clear();
- planeData_.clear();
freeBuffers_.clear();
@@ -580,12 +570,7 @@ void MainWindow::stopCapture()
camera_->requestCompleted.disconnect(this);
- for (auto &iter : mappedBuffers_) {
- const Span<uint8_t> &buffer = iter.second;
- munmap(buffer.data(), buffer.size());
- }
mappedBuffers_.clear();
- planeData_.clear();
requests_.clear();
freeQueue_.clear();
@@ -682,7 +667,7 @@ void MainWindow::processRaw(FrameBuffer *buffer,
"DNG Files (*.dng)");
if (!filename.isEmpty()) {
- uint8_t *memory = planeData_[buffer].data();
+ uint8_t *memory = mappedBuffers_[buffer]->data(0).data();
DNGWriter::write(filename.toStdString().c_str(), camera_.get(),
rawStream_->configuration(), metadata, buffer,
memory);
@@ -766,7 +751,7 @@ void MainWindow::processViewfinder(FrameBuffer *buffer)
<< "fps:" << Qt::fixed << qSetRealNumberPrecision(2) << fps;
/* Render the frame on the viewfinder. */
- viewfinder_->render(buffer, planeData_[buffer]);
+ viewfinder_->render(buffer, mappedBuffers_[buffer].get());
}
void MainWindow::queueRequest(FrameBuffer *buffer)
diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
index 28244bca..a16bea09 100644
--- a/src/qcam/main_window.h
+++ b/src/qcam/main_window.h
@@ -34,6 +34,7 @@ using namespace libcamera;
class QAction;
class QComboBox;
+class Image;
class HotplugEvent;
enum {
@@ -106,8 +107,7 @@ private:
FrameBufferAllocator *allocator_;
std::unique_ptr<CameraConfiguration> config_;
- std::map<FrameBuffer *, Span<uint8_t>> mappedBuffers_;
- std::map<FrameBuffer *, Span<uint8_t>> planeData_;
+ std::map<FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_;
/* Capture state, buffers queue and statistics */
bool isCapturing_;
diff --git a/src/qcam/meson.build b/src/qcam/meson.build
index 7d3621c9..c46f4631 100644
--- a/src/qcam/meson.build
+++ b/src/qcam/meson.build
@@ -15,6 +15,7 @@ endif
qcam_enabled = true
qcam_sources = files([
+ '../cam/image.cpp',
'../cam/options.cpp',
'../cam/stream_options.cpp',
'format_converter.cpp',
diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h
index 42d40f1f..fb462835 100644
--- a/src/qcam/viewfinder.h
+++ b/src/qcam/viewfinder.h
@@ -11,11 +11,11 @@
#include <QList>
#include <QSize>
-#include <libcamera/base/span.h>
-
#include <libcamera/formats.h>
#include <libcamera/framebuffer.h>
+class Image;
+
class ViewFinder
{
public:
@@ -24,7 +24,7 @@ public:
virtual const QList<libcamera::PixelFormat> &nativeFormats() const = 0;
virtual int setFormat(const libcamera::PixelFormat &format, const QSize &size) = 0;
- virtual void render(libcamera::FrameBuffer *buffer, libcamera::Span<uint8_t> mem) = 0;
+ virtual void render(libcamera::FrameBuffer *buffer, Image *image) = 0;
virtual void stop() = 0;
virtual QImage getCurrentImage() = 0;
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index d2ef0369..87e4fe03 100644
--- a/src/qcam/viewfinder_gl.cpp
+++ b/src/qcam/viewfinder_gl.cpp
@@ -13,6 +13,8 @@
#include <libcamera/formats.h>
+#include "../cam/image.h"
+
static const QList<libcamera::PixelFormat> supportedFormats{
/* YUV - packed (single plane) */
libcamera::formats::UYVY,
@@ -110,8 +112,7 @@ QImage ViewFinderGL::getCurrentImage()
return grabFramebuffer();
}
-void ViewFinderGL::render(libcamera::FrameBuffer *buffer,
- libcamera::Span<uint8_t> mem)
+void ViewFinderGL::render(libcamera::FrameBuffer *buffer, Image *image)
{
if (buffer->planes().size() != 1) {
qWarning() << "Multi-planar buffers are not supported";
@@ -121,7 +122,7 @@ void ViewFinderGL::render(libcamera::FrameBuffer *buffer,
if (buffer_)
renderComplete(buffer_);
- data_ = mem.data();
+ data_ = image->data(0).data();
/*
* \todo Get the stride from the buffer instead of computing it naively
*/
diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h
index 3334549e..7cd8ef33 100644
--- a/src/qcam/viewfinder_gl.h
+++ b/src/qcam/viewfinder_gl.h
@@ -39,7 +39,7 @@ public:
const QList<libcamera::PixelFormat> &nativeFormats() const override;
int setFormat(const libcamera::PixelFormat &format, const QSize &size) override;
- void render(libcamera::FrameBuffer *buffer, libcamera::Span<uint8_t> mem) override;
+ void render(libcamera::FrameBuffer *buffer, Image *image) override;
void stop() override;
QImage getCurrentImage() override;
diff --git a/src/qcam/viewfinder_qt.cpp b/src/qcam/viewfinder_qt.cpp
index a0bf99b0..fef6d53e 100644
--- a/src/qcam/viewfinder_qt.cpp
+++ b/src/qcam/viewfinder_qt.cpp
@@ -19,6 +19,7 @@
#include <libcamera/formats.h>
+#include "../cam/image.h"
#include "format_converter.h"
static const QMap<libcamera::PixelFormat, QImage::Format> nativeFormats
@@ -78,15 +79,14 @@ int ViewFinderQt::setFormat(const libcamera::PixelFormat &format,
return 0;
}
-void ViewFinderQt::render(libcamera::FrameBuffer *buffer,
- libcamera::Span<uint8_t> mem)
+void ViewFinderQt::render(libcamera::FrameBuffer *buffer, Image *image)
{
if (buffer->planes().size() != 1) {
qWarning() << "Multi-planar buffers are not supported";
return;
}
- unsigned char *memory = mem.data();
+ unsigned char *memory = image->data(0).data();
size_t size = buffer->metadata().planes()[0].bytesused;
{
diff --git a/src/qcam/viewfinder_qt.h b/src/qcam/viewfinder_qt.h
index 1a569b9c..6b48ef48 100644
--- a/src/qcam/viewfinder_qt.h
+++ b/src/qcam/viewfinder_qt.h
@@ -32,7 +32,7 @@ public:
const QList<libcamera::PixelFormat> &nativeFormats() const override;
int setFormat(const libcamera::PixelFormat &format, const QSize &size) override;
- void render(libcamera::FrameBuffer *buffer, libcamera::Span<uint8_t> mem) override;
+ void render(libcamera::FrameBuffer *buffer, Image *image) override;
void stop() override;
QImage getCurrentImage() override;