diff options
Diffstat (limited to 'src/ipa')
-rw-r--r-- | src/ipa/ipu3/ipu3.cpp | 74 | ||||
-rw-r--r-- | src/ipa/ipu3/meson.build | 4 | ||||
-rw-r--r-- | src/ipa/libipa/ipa_interface_wrapper.cpp | 287 | ||||
-rw-r--r-- | src/ipa/libipa/ipa_interface_wrapper.h | 61 | ||||
-rw-r--r-- | src/ipa/libipa/meson.build | 2 | ||||
-rw-r--r-- | src/ipa/raspberrypi/raspberrypi.cpp | 180 | ||||
-rw-r--r-- | src/ipa/rkisp1/meson.build | 2 | ||||
-rw-r--r-- | src/ipa/rkisp1/rkisp1.cpp | 63 | ||||
-rw-r--r-- | src/ipa/vimc/meson.build | 2 | ||||
-rw-r--r-- | src/ipa/vimc/vimc.cpp | 39 |
10 files changed, 145 insertions, 569 deletions
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index b11b03ef..fcd8889c 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -5,8 +5,6 @@ * ipu3.cpp - IPU3 Image Processing Algorithms */ -#include <libcamera/ipa/ipu3.h> - #include <stdint.h> #include <sys/mman.h> @@ -17,10 +15,9 @@ #include <libcamera/control_ids.h> #include <libcamera/ipa/ipa_interface.h> #include <libcamera/ipa/ipa_module_info.h> +#include <libcamera/ipa/ipu3_ipa_interface.h> #include <libcamera/request.h> -#include <libipa/ipa_interface_wrapper.h> - #include "libcamera/internal/buffer.h" #include "libcamera/internal/log.h" @@ -28,25 +25,21 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPAIPU3) -class IPAIPU3 : public IPAInterface +class IPAIPU3 : public ipa::ipu3::IPAIPU3Interface { public: int init([[maybe_unused]] const IPASettings &settings) override { return 0; } - int start([[maybe_unused]] const IPAOperationData &data, - [[maybe_unused]] IPAOperationData *result) override { return 0; } + int start() override { return 0; } void stop() override {} - void configure(const CameraSensorInfo &info, - const std::map<unsigned int, IPAStream> &streamConfig, - const std::map<unsigned int, const ControlInfoMap &> &entityControls, - const IPAOperationData &ipaConfig, - IPAOperationData *response) override; + void configure(const std::map<uint32_t, ControlInfoMap> &entityControls) override; + void mapBuffers(const std::vector<IPABuffer> &buffers) override; void unmapBuffers(const std::vector<unsigned int> &ids) override; - void processEvent(const IPAOperationData &event) override; + void processEvent(const ipa::ipu3::IPU3Event &event) override; private: void processControls(unsigned int frame, const ControlList &controls); @@ -69,11 +62,7 @@ private: uint32_t maxGain_; }; -void IPAIPU3::configure([[maybe_unused]] const CameraSensorInfo &info, - [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig, - const std::map<unsigned int, const ControlInfoMap &> &entityControls, - [[maybe_unused]] const IPAOperationData &ipaConfig, - [[maybe_unused]] IPAOperationData *result) +void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls) { if (entityControls.empty()) return; @@ -123,19 +112,15 @@ void IPAIPU3::unmapBuffers(const std::vector<unsigned int> &ids) } } -void IPAIPU3::processEvent(const IPAOperationData &event) +void IPAIPU3::processEvent(const ipa::ipu3::IPU3Event &event) { - switch (event.operation) { - case IPU3_IPA_EVENT_PROCESS_CONTROLS: { - unsigned int frame = event.data[0]; - processControls(frame, event.controls[0]); + switch (event.op) { + case ipa::ipu3::EventProcessControls: { + processControls(event.frame, event.controls); break; } - case IPU3_IPA_EVENT_STAT_READY: { - unsigned int frame = event.data[0]; - unsigned int bufferId = event.data[1]; - - auto it = buffers_.find(bufferId); + case ipa::ipu3::EventStatReady: { + auto it = buffers_.find(event.bufferId); if (it == buffers_.end()) { LOG(IPAIPU3, Error) << "Could not find stats buffer!"; return; @@ -145,14 +130,11 @@ void IPAIPU3::processEvent(const IPAOperationData &event) const ipu3_uapi_stats_3a *stats = reinterpret_cast<ipu3_uapi_stats_3a *>(mem.data()); - parseStatistics(frame, stats); + parseStatistics(event.frame, stats); break; } - case IPU3_IPA_EVENT_FILL_PARAMS: { - unsigned int frame = event.data[0]; - unsigned int bufferId = event.data[1]; - - auto it = buffers_.find(bufferId); + case ipa::ipu3::EventFillParams: { + auto it = buffers_.find(event.bufferId); if (it == buffers_.end()) { LOG(IPAIPU3, Error) << "Could not find param buffer!"; return; @@ -162,11 +144,11 @@ void IPAIPU3::processEvent(const IPAOperationData &event) ipu3_uapi_params *params = reinterpret_cast<ipu3_uapi_params *>(mem.data()); - fillParams(frame, params); + fillParams(event.frame, params); break; } default: - LOG(IPAIPU3, Error) << "Unknown event " << event.operation; + LOG(IPAIPU3, Error) << "Unknown event " << event.op; break; } } @@ -184,8 +166,8 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) /* \todo Fill in parameters buffer. */ - IPAOperationData op; - op.operation = IPU3_IPA_ACTION_PARAM_FILLED; + ipa::ipu3::IPU3Action op; + op.op = ipa::ipu3::ActionParamFilled; queueFrameAction.emit(frame, op); @@ -201,22 +183,22 @@ void IPAIPU3::parseStatistics(unsigned int frame, /* \todo React to statistics and update internal state machine. */ /* \todo Add meta-data information to ctrls. */ - IPAOperationData op; - op.operation = IPU3_IPA_ACTION_METADATA_READY; - op.controls.push_back(ctrls); + ipa::ipu3::IPU3Action op; + op.op = ipa::ipu3::ActionMetadataReady; + op.controls = ctrls; queueFrameAction.emit(frame, op); } void IPAIPU3::setControls(unsigned int frame) { - IPAOperationData op; - op.operation = IPU3_IPA_ACTION_SET_SENSOR_CONTROLS; + ipa::ipu3::IPU3Action op; + op.op = ipa::ipu3::ActionSetSensorControls; ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_)); - op.controls.push_back(ctrls); + op.controls = ctrls; queueFrameAction.emit(frame, op); } @@ -233,9 +215,9 @@ const struct IPAModuleInfo ipaModuleInfo = { "ipu3", }; -struct ipa_context *ipaCreate() +IPAInterface *ipaCreate() { - return new IPAInterfaceWrapper(std::make_unique<IPAIPU3>()); + return new IPAIPU3(); } } diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index d31594fc..a241f617 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -3,10 +3,10 @@ ipa_name = 'ipa_ipu3' mod = shared_module(ipa_name, - 'ipu3.cpp', + ['ipu3.cpp', libcamera_generated_ipa_headers], name_prefix : '', include_directories : [ipa_includes, libipa_includes], - dependencies : [libatomic, libcamera_dep], + dependencies : libcamera_dep, link_with : libipa, install : true, install_dir : ipa_install_dir) diff --git a/src/ipa/libipa/ipa_interface_wrapper.cpp b/src/ipa/libipa/ipa_interface_wrapper.cpp deleted file mode 100644 index 40628489..00000000 --- a/src/ipa/libipa/ipa_interface_wrapper.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2019, Google Inc. - * - * ipa_interface_wrapper.cpp - Image Processing Algorithm interface wrapper - */ - -#include "ipa_interface_wrapper.h" - -#include <map> -#include <string.h> -#include <unistd.h> -#include <vector> - -#include <libcamera/ipa/ipa_interface.h> - -#include "libcamera/internal/byte_stream_buffer.h" -#include "libcamera/internal/camera_sensor.h" - -/** - * \file ipa_interface_wrapper.h - * \brief Image Processing Algorithm interface wrapper - */ - -namespace libcamera { - -/** - * \class IPAInterfaceWrapper - * \brief Wrap an IPAInterface and expose it as an ipa_context - * - * This class implements the ipa_context API based on a provided IPAInterface. - * It helps IPAs that implement the IPAInterface API to provide the external - * ipa_context API. - * - * To use the wrapper, an IPA module simple creates a new instance of its - * IPAInterface implementation, and passes it to the constructor of the - * IPAInterfaceWrapper. As IPAInterfaceWrapper inherits from ipa_context, the - * constructed wrapper can then be directly returned from the IPA module's - * ipaCreate() function. - * - * \code{.cpp} - * class MyIPA : public IPAInterface - * { - * ... - * }; - * - * struct ipa_context *ipaCreate() - * { - * return new IPAInterfaceWrapper(std::make_unique<MyIPA>()); - * } - * \endcode - * - * The wrapper takes ownership of the IPAInterface and will automatically - * delete it when the wrapper is destroyed. - */ - -/** - * \brief Construct an IPAInterfaceWrapper wrapping \a interface - * \param[in] interface The interface to wrap - */ -IPAInterfaceWrapper::IPAInterfaceWrapper(std::unique_ptr<IPAInterface> interface) - : ipa_(std::move(interface)), callbacks_(nullptr), cb_ctx_(nullptr) -{ - ops = &operations_; - - ipa_->queueFrameAction.connect(this, &IPAInterfaceWrapper::queueFrameAction); -} - -void IPAInterfaceWrapper::destroy(struct ipa_context *_ctx) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - delete ctx; -} - -void *IPAInterfaceWrapper::get_interface(struct ipa_context *_ctx) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - return ctx->ipa_.get(); -} - -void IPAInterfaceWrapper::init(struct ipa_context *_ctx, - const struct ipa_settings *settings) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - IPASettings ipaSettings{ - .configurationFile = settings->configuration_file - }; - ctx->ipa_->init(ipaSettings); -} - -int IPAInterfaceWrapper::start(struct ipa_context *_ctx) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - /* \todo Translate the data and result. */ - IPAOperationData data = {}; - return ctx->ipa_->start(data, nullptr); -} - -void IPAInterfaceWrapper::stop(struct ipa_context *_ctx) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - ctx->ipa_->stop(); -} - -void IPAInterfaceWrapper::register_callbacks(struct ipa_context *_ctx, - const struct ipa_callback_ops *callbacks, - void *cb_ctx) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - ctx->callbacks_ = callbacks; - ctx->cb_ctx_ = cb_ctx; -} - -void IPAInterfaceWrapper::configure(struct ipa_context *_ctx, - const struct ipa_sensor_info *sensor_info, - const struct ipa_stream *streams, - unsigned int num_streams, - const struct ipa_control_info_map *maps, - unsigned int num_maps) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - - ctx->serializer_.reset(); - - /* Translate the IPA sensor info. */ - CameraSensorInfo sensorInfo{}; - sensorInfo.model = sensor_info->model; - sensorInfo.bitsPerPixel = sensor_info->bits_per_pixel; - sensorInfo.activeAreaSize = { sensor_info->active_area.width, - sensor_info->active_area.height }; - sensorInfo.analogCrop = { sensor_info->analog_crop.left, - sensor_info->analog_crop.top, - sensor_info->analog_crop.width, - sensor_info->analog_crop.height }; - sensorInfo.outputSize = { sensor_info->output_size.width, - sensor_info->output_size.height }; - sensorInfo.pixelRate = sensor_info->pixel_rate; - sensorInfo.lineLength = sensor_info->line_length; - - /* Translate the IPA stream configurations map. */ - std::map<unsigned int, IPAStream> ipaStreams; - - for (unsigned int i = 0; i < num_streams; ++i) { - const struct ipa_stream &stream = streams[i]; - - ipaStreams[stream.id] = { - stream.pixel_format, - Size(stream.width, stream.height), - }; - } - - /* Translate the IPA entity controls map. */ - std::map<unsigned int, const ControlInfoMap &> entityControls; - std::map<unsigned int, ControlInfoMap> infoMaps; - - for (unsigned int i = 0; i < num_maps; ++i) { - const struct ipa_control_info_map &ipa_map = maps[i]; - ByteStreamBuffer byteStream(ipa_map.data, ipa_map.size); - unsigned int id = ipa_map.id; - - infoMaps[id] = ctx->serializer_.deserialize<ControlInfoMap>(byteStream); - entityControls.emplace(id, infoMaps[id]); - } - - /* \todo Translate the ipaConfig and result. */ - IPAOperationData ipaConfig; - ctx->ipa_->configure(sensorInfo, ipaStreams, entityControls, ipaConfig, - nullptr); -} - -void IPAInterfaceWrapper::map_buffers(struct ipa_context *_ctx, - const struct ipa_buffer *_buffers, - size_t num_buffers) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - std::vector<IPABuffer> buffers(num_buffers); - - for (unsigned int i = 0; i < num_buffers; ++i) { - const struct ipa_buffer &_buffer = _buffers[i]; - IPABuffer &buffer = buffers[i]; - std::vector<FrameBuffer::Plane> &planes = buffer.planes; - - buffer.id = _buffer.id; - - planes.resize(_buffer.num_planes); - for (unsigned int j = 0; j < _buffer.num_planes; ++j) { - planes[j].fd = FileDescriptor(_buffer.planes[j].dmabuf); - planes[j].length = _buffer.planes[j].length; - } - } - - ctx->ipa_->mapBuffers(buffers); -} - -void IPAInterfaceWrapper::unmap_buffers(struct ipa_context *_ctx, - const unsigned int *_ids, - size_t num_buffers) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - std::vector<unsigned int> ids(_ids, _ids + num_buffers); - ctx->ipa_->unmapBuffers(ids); -} - -void IPAInterfaceWrapper::process_event(struct ipa_context *_ctx, - const struct ipa_operation_data *data) -{ - IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx); - IPAOperationData opData; - - opData.operation = data->operation; - - opData.data.resize(data->num_data); - memcpy(opData.data.data(), data->data, - data->num_data * sizeof(*data->data)); - - opData.controls.resize(data->num_lists); - for (unsigned int i = 0; i < data->num_lists; ++i) { - const struct ipa_control_list *c_list = &data->lists[i]; - ByteStreamBuffer byteStream(c_list->data, c_list->size); - opData.controls[i] = ctx->serializer_.deserialize<ControlList>(byteStream); - } - - ctx->ipa_->processEvent(opData); -} - -void IPAInterfaceWrapper::queueFrameAction(unsigned int frame, - const IPAOperationData &data) -{ - if (!callbacks_) - return; - - struct ipa_operation_data c_data; - c_data.operation = data.operation; - c_data.data = data.data.data(); - c_data.num_data = data.data.size(); - - struct ipa_control_list control_lists[data.controls.size()]; - c_data.lists = control_lists; - c_data.num_lists = data.controls.size(); - - std::size_t listsSize = 0; - for (const auto &list : data.controls) - listsSize += serializer_.binarySize(list); - - std::vector<uint8_t> binaryData(listsSize); - ByteStreamBuffer byteStreamBuffer(binaryData.data(), listsSize); - - unsigned int i = 0; - for (const auto &list : data.controls) { - struct ipa_control_list &c_list = control_lists[i]; - c_list.size = serializer_.binarySize(list); - - ByteStreamBuffer b = byteStreamBuffer.carveOut(c_list.size); - serializer_.serialize(list, b); - - c_list.data = b.base(); - } - - callbacks_->queue_frame_action(cb_ctx_, frame, c_data); -} - -#ifndef __DOXYGEN__ -/* - * This construct confuses Doygen and makes it believe that all members of the - * operations is a member of IPAInterfaceWrapper. It must thus be hidden. - */ -const struct ipa_context_ops IPAInterfaceWrapper::operations_ = { - .destroy = &IPAInterfaceWrapper::destroy, - .get_interface = &IPAInterfaceWrapper::get_interface, - .init = &IPAInterfaceWrapper::init, - .start = &IPAInterfaceWrapper::start, - .stop = &IPAInterfaceWrapper::stop, - .register_callbacks = &IPAInterfaceWrapper::register_callbacks, - .configure = &IPAInterfaceWrapper::configure, - .map_buffers = &IPAInterfaceWrapper::map_buffers, - .unmap_buffers = &IPAInterfaceWrapper::unmap_buffers, - .process_event = &IPAInterfaceWrapper::process_event, -}; -#endif - -} /* namespace libcamera */ diff --git a/src/ipa/libipa/ipa_interface_wrapper.h b/src/ipa/libipa/ipa_interface_wrapper.h deleted file mode 100644 index a1c70159..00000000 --- a/src/ipa/libipa/ipa_interface_wrapper.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2019, Google Inc. - * - * ipa_interface_wrapper.h - Image Processing Algorithm interface wrapper - */ -#ifndef __LIBCAMERA_IPA_INTERFACE_WRAPPER_H__ -#define __LIBCAMERA_IPA_INTERFACE_WRAPPER_H__ - -#include <memory> - -#include <libcamera/ipa/ipa_interface.h> - -#include "libcamera/internal/control_serializer.h" - -namespace libcamera { - -class IPAInterfaceWrapper : public ipa_context -{ -public: - IPAInterfaceWrapper(std::unique_ptr<IPAInterface> interface); - -private: - static void destroy(struct ipa_context *ctx); - static void *get_interface(struct ipa_context *ctx); - static void init(struct ipa_context *ctx, - const struct ipa_settings *settings); - static int start(struct ipa_context *ctx); - static void stop(struct ipa_context *ctx); - static void register_callbacks(struct ipa_context *ctx, - const struct ipa_callback_ops *callbacks, - void *cb_ctx); - static void configure(struct ipa_context *ctx, - const struct ipa_sensor_info *sensor_info, - const struct ipa_stream *streams, - unsigned int num_streams, - const struct ipa_control_info_map *maps, - unsigned int num_maps); - static void map_buffers(struct ipa_context *ctx, - const struct ipa_buffer *c_buffers, - size_t num_buffers); - static void unmap_buffers(struct ipa_context *ctx, - const unsigned int *ids, - size_t num_buffers); - static void process_event(struct ipa_context *ctx, - const struct ipa_operation_data *data); - - static const struct ipa_context_ops operations_; - - void queueFrameAction(unsigned int frame, const IPAOperationData &data); - - std::unique_ptr<IPAInterface> ipa_; - const struct ipa_callback_ops *callbacks_; - void *cb_ctx_; - - ControlSerializer serializer_; -}; - -} /* namespace libcamera */ - -#endif /* __LIBCAMERA_IPA_INTERFACE_WRAPPER_H__ */ diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build index 22626405..b29ef0f4 100644 --- a/src/ipa/libipa/meson.build +++ b/src/ipa/libipa/meson.build @@ -1,11 +1,9 @@ # SPDX-License-Identifier: CC0-1.0 libipa_headers = files([ - 'ipa_interface_wrapper.h', ]) libipa_sources = files([ - 'ipa_interface_wrapper.cpp', ]) libipa_includes = include_directories('..') diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index ef8b19ba..81a3195c 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -20,11 +20,10 @@ #include <libcamera/ipa/ipa_interface.h> #include <libcamera/ipa/ipa_module_info.h> #include <libcamera/ipa/raspberrypi.h> +#include <libcamera/ipa/raspberrypi_ipa_interface.h> #include <libcamera/request.h> #include <libcamera/span.h> -#include <libipa/ipa_interface_wrapper.h> - #include "libcamera/internal/buffer.h" #include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/log.h" @@ -64,7 +63,7 @@ constexpr double defaultMaxFrameDuration = 1e6 / 0.01; LOG_DEFINE_CATEGORY(IPARPI) -class IPARPi : public IPAInterface +class IPARPi : public ipa::rpi::IPARPiInterface { public: IPARPi() @@ -77,21 +76,24 @@ public: ~IPARPi() { if (lsTable_) - munmap(lsTable_, RPi::MaxLsGridSize); + munmap(lsTable_, ipa::rpi::MaxLsGridSize); } int init(const IPASettings &settings) override; - int start(const IPAOperationData &data, IPAOperationData *result) override; + void start(const ipa::rpi::StartControls &data, + ipa::rpi::StartControls *result) override; void stop() override {} void configure(const CameraSensorInfo &sensorInfo, const std::map<unsigned int, IPAStream> &streamConfig, - const std::map<unsigned int, const ControlInfoMap &> &entityControls, - const IPAOperationData &ipaConfig, - IPAOperationData *response) override; + const std::map<unsigned int, ControlInfoMap> &entityControls, + const ipa::rpi::ConfigInput &data, + ipa::rpi::ConfigOutput *response, int32_t *ret) override; void mapBuffers(const std::vector<IPABuffer> &buffers) override; void unmapBuffers(const std::vector<unsigned int> &ids) override; - void processEvent(const IPAOperationData &event) override; + void signalStatReady(const uint32_t bufferId) override; + void signalQueueRequest(const ControlList &controls) override; + void signalIspPrepare(const ipa::rpi::ISPConfig &data) override; private: void setMode(const CameraSensorInfo &sensorInfo); @@ -166,15 +168,15 @@ int IPARPi::init(const IPASettings &settings) return 0; } -int IPARPi::start(const IPAOperationData &data, IPAOperationData *result) +void IPARPi::start(const ipa::rpi::StartControls &data, + ipa::rpi::StartControls *result) { RPiController::Metadata metadata; ASSERT(result); - result->operation = 0; - if (data.operation & RPi::IPA_CONFIG_STARTUP_CTRLS) { + if (!data.controls.empty()) { /* We have been given some controls to action before start. */ - queueRequest(data.controls[0]); + queueRequest(data.controls); } controller_.SwitchMode(mode_, &metadata); @@ -189,8 +191,7 @@ int IPARPi::start(const IPAOperationData &data, IPAOperationData *result) if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) { ControlList ctrls(sensorCtrls_); applyAGC(&agcStatus, ctrls); - result->controls.emplace_back(ctrls); - result->operation |= RPi::IPA_RESULT_SENSOR_CTRLS; + result->controls = std::move(ctrls); } /* @@ -237,12 +238,9 @@ int IPARPi::start(const IPAOperationData &data, IPAOperationData *result) mistrustCount_ = helper_->MistrustFramesModeSwitch(); } - result->data.push_back(dropFrame); - result->operation |= RPi::IPA_RESULT_DROP_FRAMES; + result->dropFrameCount = dropFrame; firstStart_ = false; - - return 0; } void IPARPi::setMode(const CameraSensorInfo &sensorInfo) @@ -292,30 +290,30 @@ void IPARPi::setMode(const CameraSensorInfo &sensorInfo) void IPARPi::configure(const CameraSensorInfo &sensorInfo, [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig, - const std::map<unsigned int, const ControlInfoMap &> &entityControls, - const IPAOperationData &ipaConfig, - IPAOperationData *result) + const std::map<unsigned int, ControlInfoMap> &entityControls, + const ipa::rpi::ConfigInput &ipaConfig, + ipa::rpi::ConfigOutput *result, int32_t *ret) { if (entityControls.size() != 2) { LOG(IPARPI, Error) << "No ISP or sensor controls found."; - result->operation = RPi::IPA_RESULT_CONFIG_FAILED; + *ret = -1; return; } - result->operation = 0; + result->params = 0; sensorCtrls_ = entityControls.at(0); ispCtrls_ = entityControls.at(1); if (!validateSensorControls()) { LOG(IPARPI, Error) << "Sensor control validation failed."; - result->operation = RPi::IPA_RESULT_CONFIG_FAILED; + *ret = -1; return; } if (!validateIspControls()) { LOG(IPARPI, Error) << "ISP control validation failed."; - result->operation = RPi::IPA_RESULT_CONFIG_FAILED; + *ret = -1; return; } @@ -334,7 +332,7 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, if (!helper_) { LOG(IPARPI, Error) << "Could not create camera helper for " << cameraName; - result->operation = RPi::IPA_RESULT_CONFIG_FAILED; + *ret = -1; return; } @@ -346,35 +344,30 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, helper_->GetDelays(exposureDelay, gainDelay); sensorMetadata = helper_->SensorEmbeddedDataPresent(); - result->data.push_back(gainDelay); - result->data.push_back(exposureDelay); /* For EXPOSURE ctrl */ - result->data.push_back(exposureDelay); /* For VBLANK ctrl */ - result->data.push_back(sensorMetadata); - - result->operation |= RPi::IPA_RESULT_SENSOR_PARAMS; + result->params |= ipa::rpi::ConfigStaggeredWrite; + result->sensorConfig.gainDelay = gainDelay; + result->sensorConfig.exposureDelay = exposureDelay; + result->sensorConfig.vblank = exposureDelay; + result->sensorConfig.sensorMetadata = sensorMetadata; } /* Re-assemble camera mode using the sensor info. */ setMode(sensorInfo); - /* - * The ipaConfig.data always gives us the user transform first. Note that - * this will always make the LS table pointer (if present) element 1. - */ - mode_.transform = static_cast<libcamera::Transform>(ipaConfig.data[0]); + mode_.transform = static_cast<libcamera::Transform>(ipaConfig.transform); /* Store the lens shading table pointer and handle if available. */ - if (ipaConfig.operation & RPi::IPA_CONFIG_LS_TABLE) { + if (ipaConfig.lsTableHandle.isValid()) { /* Remove any previous table, if there was one. */ if (lsTable_) { - munmap(lsTable_, RPi::MaxLsGridSize); + munmap(lsTable_, ipa::rpi::MaxLsGridSize); lsTable_ = nullptr; } - /* Map the LS table buffer into user space (now element 1). */ - lsTableHandle_ = FileDescriptor(ipaConfig.data[1]); + /* Map the LS table buffer into user space. */ + lsTableHandle_ = std::move(ipaConfig.lsTableHandle); if (lsTableHandle_.isValid()) { - lsTable_ = mmap(nullptr, RPi::MaxLsGridSize, PROT_READ | PROT_WRITE, + lsTable_ = mmap(nullptr, ipa::rpi::MaxLsGridSize, PROT_READ | PROT_WRITE, MAP_SHARED, lsTableHandle_.fd(), 0); if (lsTable_ == MAP_FAILED) { @@ -403,11 +396,12 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, agcStatus.analogue_gain = DefaultAnalogueGain; applyAGC(&agcStatus, ctrls); - result->controls.emplace_back(ctrls); - result->operation |= RPi::IPA_RESULT_SENSOR_CTRLS; + result->controls = std::move(ctrls); } lastMode_ = mode_; + + *ret = 0; } void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers) @@ -429,56 +423,35 @@ void IPARPi::unmapBuffers(const std::vector<unsigned int> &ids) } } -void IPARPi::processEvent(const IPAOperationData &event) +void IPARPi::signalStatReady(uint32_t bufferId) { - switch (event.operation) { - case RPi::IPA_EVENT_SIGNAL_STAT_READY: { - unsigned int bufferId = event.data[0]; - - if (++checkCount_ != frameCount_) /* assert here? */ - LOG(IPARPI, Error) << "WARNING: Prepare/Process mismatch!!!"; - if (frameCount_ > mistrustCount_) - processStats(bufferId); - - reportMetadata(); - - IPAOperationData op; - op.operation = RPi::IPA_ACTION_STATS_METADATA_COMPLETE; - op.data = { bufferId & RPi::BufferMask::ID }; - op.controls = { libcameraMetadata_ }; - queueFrameAction.emit(0, op); - break; - } + if (++checkCount_ != frameCount_) /* assert here? */ + LOG(IPARPI, Error) << "WARNING: Prepare/Process mismatch!!!"; + if (frameCount_ > mistrustCount_) + processStats(bufferId); - case RPi::IPA_EVENT_SIGNAL_ISP_PREPARE: { - unsigned int embeddedbufferId = event.data[0]; - unsigned int bayerbufferId = event.data[1]; + reportMetadata(); - /* - * At start-up, or after a mode-switch, we may want to - * avoid running the control algos for a few frames in case - * they are "unreliable". - */ - prepareISP(embeddedbufferId); - frameCount_++; - - /* Ready to push the input buffer into the ISP. */ - IPAOperationData op; - op.operation = RPi::IPA_ACTION_RUN_ISP; - op.data = { bayerbufferId & RPi::BufferMask::ID }; - queueFrameAction.emit(0, op); - break; - } + statsMetadataComplete.emit(bufferId & ipa::rpi::MaskID, libcameraMetadata_); +} - case RPi::IPA_EVENT_QUEUE_REQUEST: { - queueRequest(event.controls[0]); - break; - } +void IPARPi::signalQueueRequest(const ControlList &controls) +{ + queueRequest(controls); +} - default: - LOG(IPARPI, Error) << "Unknown event " << event.operation; - break; - } +void IPARPi::signalIspPrepare(const ipa::rpi::ISPConfig &data) +{ + /* + * At start-up, or after a mode-switch, we may want to + * avoid running the control algos for a few frames in case + * they are "unreliable". + */ + prepareISP(data.embeddedbufferId); + frameCount_++; + + /* Ready to push the input buffer into the ISP. */ + runIsp.emit(data.bayerbufferId & ipa::rpi::MaskID); } void IPARPi::reportMetadata() @@ -933,10 +906,7 @@ void IPARPi::queueRequest(const ControlList &controls) void IPARPi::returnEmbeddedBuffer(unsigned int bufferId) { - IPAOperationData op; - op.operation = RPi::IPA_ACTION_EMBEDDED_COMPLETE; - op.data = { bufferId & RPi::BufferMask::ID }; - queueFrameAction.emit(0, op); + embeddedComplete.emit(bufferId & ipa::rpi::MaskID); } void IPARPi::prepareISP(unsigned int bufferId) @@ -997,12 +967,8 @@ void IPARPi::prepareISP(unsigned int bufferId) if (dpcStatus) applyDPC(dpcStatus, ctrls); - if (!ctrls.empty()) { - IPAOperationData op; - op.operation = RPi::IPA_ACTION_V4L2_SET_ISP; - op.controls.push_back(ctrls); - queueFrameAction.emit(0, op); - } + if (!ctrls.empty()) + setIsp.emit(ctrls); } } @@ -1059,10 +1025,7 @@ void IPARPi::processStats(unsigned int bufferId) ControlList ctrls(sensorCtrls_); applyAGC(&agcStatus, ctrls); - IPAOperationData op; - op.operation = RPi::IPA_ACTION_SET_DELAYED_CTRLS; - op.controls.emplace_back(ctrls); - queueFrameAction.emit(0, op); + setDelayedControls.emit(ctrls); } } @@ -1301,13 +1264,14 @@ void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) .grid_width = w, .grid_stride = w, .grid_height = h, - .dmabuf = lsTableHandle_.fd(), + /* .dmabuf will be filled in by pipeline handler. */ + .dmabuf = 0, .ref_transform = 0, .corner_sampled = 1, .gain_format = GAIN_FORMAT_U4P10 }; - if (!lsTable_ || w * h * 4 * sizeof(uint16_t) > RPi::MaxLsGridSize) { + if (!lsTable_ || w * h * 4 * sizeof(uint16_t) > ipa::rpi::MaxLsGridSize) { LOG(IPARPI, Error) << "Do not have a correctly allocate lens shading table!"; return; } @@ -1378,9 +1342,9 @@ const struct IPAModuleInfo ipaModuleInfo = { "raspberrypi", }; -struct ipa_context *ipaCreate() +IPAInterface *ipaCreate() { - return new IPAInterfaceWrapper(std::make_unique<IPARPi>()); + return new IPARPi(); } } /* extern "C" */ diff --git a/src/ipa/rkisp1/meson.build b/src/ipa/rkisp1/meson.build index 95eb5393..1a1c7159 100644 --- a/src/ipa/rkisp1/meson.build +++ b/src/ipa/rkisp1/meson.build @@ -3,7 +3,7 @@ ipa_name = 'ipa_rkisp1' mod = shared_module(ipa_name, - 'rkisp1.cpp', + ['rkisp1.cpp', libcamera_generated_ipa_headers], name_prefix : '', include_directories : [ipa_includes, libipa_includes], dependencies : libcamera_dep, diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 39783abd..67bac986 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -19,36 +19,31 @@ #include <libcamera/control_ids.h> #include <libcamera/ipa/ipa_interface.h> #include <libcamera/ipa/ipa_module_info.h> -#include <libcamera/ipa/rkisp1.h> +#include <libcamera/ipa/rkisp1_ipa_interface.h> #include <libcamera/request.h> -#include <libipa/ipa_interface_wrapper.h> - #include "libcamera/internal/log.h" namespace libcamera { LOG_DEFINE_CATEGORY(IPARkISP1) -class IPARkISP1 : public IPAInterface +class IPARkISP1 : public ipa::rkisp1::IPARkISP1Interface { public: int init([[maybe_unused]] const IPASettings &settings) override { return 0; } - int start([[maybe_unused]] const IPAOperationData &data, - [[maybe_unused]] IPAOperationData *result) override { return 0; } + int start() override { return 0; } void stop() override {} void configure(const CameraSensorInfo &info, - const std::map<unsigned int, IPAStream> &streamConfig, - const std::map<unsigned int, const ControlInfoMap &> &entityControls, - const IPAOperationData &ipaConfig, - IPAOperationData *response) override; + const std::map<uint32_t, IPAStream> &streamConfig, + const std::map<uint32_t, ControlInfoMap> &entityControls) override; void mapBuffers(const std::vector<IPABuffer> &buffers) override; void unmapBuffers(const std::vector<unsigned int> &ids) override; - void processEvent(const IPAOperationData &event) override; + void processEvent(const ipa::rkisp1::RkISP1Event &event) override; private: void queueRequest(unsigned int frame, rkisp1_params_cfg *params, @@ -81,10 +76,8 @@ private: * before accessing them. */ void IPARkISP1::configure([[maybe_unused]] const CameraSensorInfo &info, - [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig, - const std::map<unsigned int, const ControlInfoMap &> &entityControls, - [[maybe_unused]] const IPAOperationData &ipaConfig, - [[maybe_unused]] IPAOperationData *result) + [[maybe_unused]] const std::map<uint32_t, IPAStream> &streamConfig, + const std::map<uint32_t, ControlInfoMap> &entityControls) { if (entityControls.empty()) return; @@ -160,12 +153,12 @@ void IPARkISP1::unmapBuffers(const std::vector<unsigned int> &ids) } } -void IPARkISP1::processEvent(const IPAOperationData &event) +void IPARkISP1::processEvent(const ipa::rkisp1::RkISP1Event &event) { - switch (event.operation) { - case RKISP1_IPA_EVENT_SIGNAL_STAT_BUFFER: { - unsigned int frame = event.data[0]; - unsigned int bufferId = event.data[1]; + switch (event.op) { + case ipa::rkisp1::EventSignalStatBuffer: { + unsigned int frame = event.frame; + unsigned int bufferId = event.bufferId; const rkisp1_stat_buffer *stats = static_cast<rkisp1_stat_buffer *>(buffersMemory_[bufferId]); @@ -173,18 +166,18 @@ void IPARkISP1::processEvent(const IPAOperationData &event) updateStatistics(frame, stats); break; } - case RKISP1_IPA_EVENT_QUEUE_REQUEST: { - unsigned int frame = event.data[0]; - unsigned int bufferId = event.data[1]; + case ipa::rkisp1::EventQueueRequest: { + unsigned int frame = event.frame; + unsigned int bufferId = event.bufferId; rkisp1_params_cfg *params = static_cast<rkisp1_params_cfg *>(buffersMemory_[bufferId]); - queueRequest(frame, params, event.controls[0]); + queueRequest(frame, params, event.controls); break; } default: - LOG(IPARkISP1, Error) << "Unknown event " << event.operation; + LOG(IPARkISP1, Error) << "Unknown event " << event.op; break; } } @@ -204,8 +197,8 @@ void IPARkISP1::queueRequest(unsigned int frame, rkisp1_params_cfg *params, params->module_en_update = RKISP1_CIF_ISP_MODULE_AEC; } - IPAOperationData op; - op.operation = RKISP1_IPA_ACTION_PARAM_FILLED; + ipa::rkisp1::RkISP1Action op; + op.op = ipa::rkisp1::ActionParamFilled; queueFrameAction.emit(frame, op); } @@ -257,13 +250,13 @@ void IPARkISP1::updateStatistics(unsigned int frame, void IPARkISP1::setControls(unsigned int frame) { - IPAOperationData op; - op.operation = RKISP1_IPA_ACTION_V4L2_SET; + ipa::rkisp1::RkISP1Action op; + op.op = ipa::rkisp1::ActionV4L2Set; ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_)); - op.controls.push_back(ctrls); + op.controls = ctrls; queueFrameAction.emit(frame, op); } @@ -275,9 +268,9 @@ void IPARkISP1::metadataReady(unsigned int frame, unsigned int aeState) if (aeState) ctrls.set(controls::AeLocked, aeState == 2); - IPAOperationData op; - op.operation = RKISP1_IPA_ACTION_METADATA; - op.controls.push_back(ctrls); + ipa::rkisp1::RkISP1Action op; + op.op = ipa::rkisp1::ActionMetadata; + op.controls = ctrls; queueFrameAction.emit(frame, op); } @@ -294,9 +287,9 @@ const struct IPAModuleInfo ipaModuleInfo = { "rkisp1", }; -struct ipa_context *ipaCreate() +IPAInterface *ipaCreate() { - return new IPAInterfaceWrapper(std::make_unique<IPARkISP1>()); + return new IPARkISP1(); } } diff --git a/src/ipa/vimc/meson.build b/src/ipa/vimc/meson.build index b1544c28..a35825ae 100644 --- a/src/ipa/vimc/meson.build +++ b/src/ipa/vimc/meson.build @@ -3,7 +3,7 @@ ipa_name = 'ipa_vimc' mod = shared_module(ipa_name, - 'vimc.cpp', + ['vimc.cpp', libcamera_generated_ipa_headers], name_prefix : '', include_directories : [ipa_includes, libipa_includes], dependencies : libcamera_dep, diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp index 074902ee..13681d88 100644 --- a/src/ipa/vimc/vimc.cpp +++ b/src/ipa/vimc/vimc.cpp @@ -5,7 +5,7 @@ * ipa_vimc.cpp - Vimc Image Processing Algorithm module */ -#include <libcamera/ipa/vimc.h> +#include <libcamera/ipa/vimc_ipa_interface.h> #include <fcntl.h> #include <string.h> @@ -17,8 +17,6 @@ #include <libcamera/ipa/ipa_interface.h> #include <libcamera/ipa/ipa_module_info.h> -#include <libipa/ipa_interface_wrapper.h> - #include "libcamera/internal/file.h" #include "libcamera/internal/log.h" @@ -26,7 +24,7 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPAVimc) -class IPAVimc : public IPAInterface +class IPAVimc : public ipa::vimc::IPAVimcInterface { public: IPAVimc(); @@ -34,22 +32,12 @@ public: int init(const IPASettings &settings) override; - int start(const IPAOperationData &data, - IPAOperationData *result) override; + int start() override; void stop() override; - void configure([[maybe_unused]] const CameraSensorInfo &sensorInfo, - [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig, - [[maybe_unused]] const std::map<unsigned int, const ControlInfoMap &> &entityControls, - [[maybe_unused]] const IPAOperationData &ipaConfig, - [[maybe_unused]] IPAOperationData *result) override {} - void mapBuffers([[maybe_unused]] const std::vector<IPABuffer> &buffers) override {} - void unmapBuffers([[maybe_unused]] const std::vector<unsigned int> &ids) override {} - void processEvent([[maybe_unused]] const IPAOperationData &event) override {} - private: void initTrace(); - void trace(enum IPAOperationCode operation); + void trace(enum ipa::vimc::IPAOperationCode operation); int fd_; }; @@ -68,7 +56,7 @@ IPAVimc::~IPAVimc() int IPAVimc::init(const IPASettings &settings) { - trace(IPAOperationInit); + trace(ipa::vimc::IPAOperationInit); LOG(IPAVimc, Debug) << "initializing vimc IPA with configuration file " @@ -83,10 +71,9 @@ int IPAVimc::init(const IPASettings &settings) return 0; } -int IPAVimc::start([[maybe_unused]] const IPAOperationData &data, - [[maybe_unused]] IPAOperationData *result) +int IPAVimc::start() { - trace(IPAOperationStart); + trace(ipa::vimc::IPAOperationStart); LOG(IPAVimc, Debug) << "start vimc IPA!"; @@ -95,7 +82,7 @@ int IPAVimc::start([[maybe_unused]] const IPAOperationData &data, void IPAVimc::stop() { - trace(IPAOperationStop); + trace(ipa::vimc::IPAOperationStop); LOG(IPAVimc, Debug) << "stop vimc IPA!"; } @@ -103,11 +90,11 @@ void IPAVimc::stop() void IPAVimc::initTrace() { struct stat fifoStat; - int ret = stat(VIMC_IPA_FIFO_PATH, &fifoStat); + int ret = stat(ipa::vimc::VimcIPAFIFOPath.c_str(), &fifoStat); if (ret) return; - ret = ::open(VIMC_IPA_FIFO_PATH, O_WRONLY); + ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY); if (ret < 0) { ret = errno; LOG(IPAVimc, Error) << "Failed to open vimc IPA test FIFO: " @@ -118,7 +105,7 @@ void IPAVimc::initTrace() fd_ = ret; } -void IPAVimc::trace(enum IPAOperationCode operation) +void IPAVimc::trace(enum ipa::vimc::IPAOperationCode operation) { if (fd_ < 0) return; @@ -143,9 +130,9 @@ const struct IPAModuleInfo ipaModuleInfo = { "vimc", }; -struct ipa_context *ipaCreate() +IPAInterface *ipaCreate() { - return new IPAInterfaceWrapper(std::make_unique<IPAVimc>()); + return new IPAVimc(); } } |