diff options
-rw-r--r-- | Documentation/guides/application-developer.rst | 2 | ||||
-rw-r--r-- | include/libcamera/base/object.h | 3 | ||||
-rw-r--r-- | include/libcamera/base/thread.h | 3 | ||||
-rw-r--r-- | include/libcamera/internal/matrix.h | 2 | ||||
-rw-r--r-- | include/libcamera/internal/software_isp/software_isp.h | 3 | ||||
-rw-r--r-- | src/apps/common/ppm_writer.cpp | 6 | ||||
-rw-r--r-- | src/ipa/rkisp1/algorithms/ccm.cpp | 7 | ||||
-rw-r--r-- | src/libcamera/matrix.cpp | 11 | ||||
-rw-r--r-- | src/libcamera/pipeline/simple/simple.cpp | 16 | ||||
-rw-r--r-- | src/libcamera/pipeline/virtual/virtual.cpp | 23 | ||||
-rw-r--r-- | src/libcamera/pipeline/virtual/virtual.h | 1 |
11 files changed, 47 insertions, 30 deletions
diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst index 25beb55d..f3798d17 100644 --- a/Documentation/guides/application-developer.rst +++ b/Documentation/guides/application-developer.rst @@ -128,7 +128,7 @@ available. std::string cameraId = cameras[0]->id(); - auto camera = cm->get(cameraId); + camera = cm->get(cameraId); /* * Note that `camera` may not compare equal to `cameras[0]`. * In fact, it might simply be a `nullptr`, as the particular diff --git a/include/libcamera/base/object.h b/include/libcamera/base/object.h index 508773cd..6cb935a0 100644 --- a/include/libcamera/base/object.h +++ b/include/libcamera/base/object.h @@ -12,6 +12,7 @@ #include <vector> #include <libcamera/base/bound_method.h> +#include <libcamera/base/class.h> namespace libcamera { @@ -52,6 +53,8 @@ protected: bool assertThreadBound(const char *message); private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(Object) + friend class SignalBase; friend class Thread; diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h index 3209d4f7..3cbf6398 100644 --- a/include/libcamera/base/thread.h +++ b/include/libcamera/base/thread.h @@ -13,6 +13,7 @@ #include <libcamera/base/private.h> +#include <libcamera/base/class.h> #include <libcamera/base/message.h> #include <libcamera/base/signal.h> #include <libcamera/base/span.h> @@ -54,6 +55,8 @@ protected: virtual void run(); private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(Thread) + void startThread(); void finishThread(); diff --git a/include/libcamera/internal/matrix.h b/include/libcamera/internal/matrix.h index 7a71028c..a055e692 100644 --- a/include/libcamera/internal/matrix.h +++ b/include/libcamera/internal/matrix.h @@ -66,6 +66,8 @@ public: return out.str(); } + Span<const T, Rows * Cols> data() const { return data_; } + Span<const T, Cols> operator[](size_t i) const { return Span<const T, Cols>{ &data_.data()[i * Cols], Cols }; diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index d51b03fd..440a296d 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -18,6 +18,7 @@ #include <libcamera/base/class.h> #include <libcamera/base/log.h> +#include <libcamera/base/object.h> #include <libcamera/base/signal.h> #include <libcamera/base/thread.h> @@ -43,7 +44,7 @@ struct StreamConfiguration; LOG_DECLARE_CATEGORY(SoftwareIsp) -class SoftwareIsp +class SoftwareIsp : public Object { public: SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, diff --git a/src/apps/common/ppm_writer.cpp b/src/apps/common/ppm_writer.cpp index 2e9378aa..368de8bf 100644 --- a/src/apps/common/ppm_writer.cpp +++ b/src/apps/common/ppm_writer.cpp @@ -29,7 +29,7 @@ int PPMWriter::write(const char *filename, std::ofstream output(filename, std::ios::binary); if (!output) { std::cerr << "Failed to open ppm file: " << filename << std::endl; - return -EINVAL; + return -EIO; } output << "P6" << std::endl @@ -37,7 +37,7 @@ int PPMWriter::write(const char *filename, << "255" << std::endl; if (!output) { std::cerr << "Failed to write the file header" << std::endl; - return -EINVAL; + return -EIO; } const unsigned int rowLength = config.size.width * 3; @@ -46,7 +46,7 @@ int PPMWriter::write(const char *filename, output.write(row, rowLength); if (!output) { std::cerr << "Failed to write image data at row " << y << std::endl; - return -EINVAL; + return -EIO; } } diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp index e2b5cf4d..eb8ca39e 100644 --- a/src/ipa/rkisp1/algorithms/ccm.cpp +++ b/src/ipa/rkisp1/algorithms/ccm.cpp @@ -120,12 +120,7 @@ void Ccm::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const rkisp1_stat_buffer *stats, ControlList &metadata) { - float m[9]; - for (unsigned int i = 0; i < 3; i++) { - for (unsigned int j = 0; j < 3; j++) - m[i * 3 + j] = frameContext.ccm.ccm[i][j]; - } - metadata.set(controls::ColourCorrectionMatrix, m); + metadata.set(controls::ColourCorrectionMatrix, frameContext.ccm.ccm.data()); } REGISTER_IPA_ALGORITHM(Ccm, "Ccm") diff --git a/src/libcamera/matrix.cpp b/src/libcamera/matrix.cpp index 4d95a19b..e7e02722 100644 --- a/src/libcamera/matrix.cpp +++ b/src/libcamera/matrix.cpp @@ -53,6 +53,17 @@ LOG_DEFINE_CATEGORY(Matrix) */ /** + * \fn Matrix::data() + * \brief Access the matrix data as a linear array + * + * Access the contents of the matrix as a one-dimensional linear array of + * values in row-major order. The size of the array is equal to the product of + * the number of rows and columns of the matrix (Rows x Cols). + * + * \return A span referencing the matrix data as a linear array + */ + +/** * \fn Span<const T, Cols> Matrix::operator[](size_t i) const * \brief Index to a row in the matrix * \param[in] i Index of row to retrieve diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 8ac24e6e..6e039bf3 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -537,21 +537,7 @@ int SimpleCameraData::init() << "Failed to create software ISP, disabling software debayering"; swIsp_.reset(); } else { - /* - * The inputBufferReady signal is emitted from the soft ISP thread, - * and needs to be handled in the pipeline handler thread. Signals - * implement queued delivery, but this works transparently only if - * the receiver is bound to the target thread. As the - * SimpleCameraData class doesn't inherit from the Object class, it - * is not bound to any thread, and the signal would be delivered - * synchronously. Instead, connect the signal to a lambda function - * bound explicitly to the pipe, which is bound to the pipeline - * handler thread. The function then simply forwards the call to - * conversionInputDone(). - */ - swIsp_->inputBufferReady.connect(pipe, [this](FrameBuffer *buffer) { - this->conversionInputDone(buffer); - }); + swIsp_->inputBufferReady.connect(this, &SimpleCameraData::conversionInputDone); swIsp_->outputBufferReady.connect(this, &SimpleCameraData::conversionOutputDone); swIsp_->ispStatsReady.connect(this, &SimpleCameraData::ispStatsReady); swIsp_->setSensorControls.connect(this, &SimpleCameraData::setSensorControls); diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 469f5655..049ebcba 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -232,8 +232,7 @@ PipelineHandlerVirtual::generateConfiguration(Camera *camera, default: LOG(Virtual, Error) << "Requested stream role not supported: " << role; - config.reset(); - return config; + return {}; } std::map<PixelFormat, std::vector<SizeRange>> streamFormats; @@ -287,6 +286,11 @@ int PipelineHandlerVirtual::exportFrameBuffers([[maybe_unused]] Camera *camera, int PipelineHandlerVirtual::start([[maybe_unused]] Camera *camera, [[maybe_unused]] const ControlList *controls) { + VirtualCameraData *data = cameraData(camera); + + for (auto &s : data->streamConfigs_) + s.seq = 0; + return 0; } @@ -298,16 +302,27 @@ int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera, Request *request) { VirtualCameraData *data = cameraData(camera); + const auto timestamp = currentTimestamp(); for (auto const &[stream, buffer] : request->buffers()) { bool found = false; /* map buffer and fill test patterns */ for (auto &streamConfig : data->streamConfigs_) { if (stream == &streamConfig.stream) { + FrameMetadata &fmd = buffer->_d()->metadata(); + + fmd.status = FrameMetadata::Status::FrameSuccess; + fmd.sequence = streamConfig.seq++; + fmd.timestamp = timestamp; + + for (const auto [i, p] : utils::enumerate(buffer->planes())) + fmd.planes()[i].bytesused = p.length; + found = true; + if (streamConfig.frameGenerator->generateFrame( stream->configuration().size, buffer)) - buffer->_d()->cancel(); + fmd.status = FrameMetadata::Status::FrameError; completeBuffer(request, buffer); break; @@ -316,7 +331,7 @@ int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera, ASSERT(found); } - request->metadata().set(controls::SensorTimestamp, currentTimestamp()); + request->metadata().set(controls::SensorTimestamp, timestamp); completeRequest(request); return 0; diff --git a/src/libcamera/pipeline/virtual/virtual.h b/src/libcamera/pipeline/virtual/virtual.h index 92ad7d4a..683cb82b 100644 --- a/src/libcamera/pipeline/virtual/virtual.h +++ b/src/libcamera/pipeline/virtual/virtual.h @@ -37,6 +37,7 @@ public: struct StreamConfig { Stream stream; std::unique_ptr<FrameGenerator> frameGenerator; + unsigned int seq = 0; }; /* The config file is parsed to the Configuration struct */ struct Configuration { |