mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-18 18:05:09 +03:00
ipa: Allow short-circuiting the ipa_context_ops
When an IPA module is loaded without isolation and implements the IPAInterface internally, going through ipa_context_ops is a waste of time. Add an operation to retrieve the IPAInterface, and use it directly in the IPAContextWrapper. For debugging purpose, make it possible to forcing usage of the C API by defining the LIBCAMERA_IPA_FORCE_C_API environment variable. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
8162ac1647
commit
d7e0985ce1
6 changed files with 64 additions and 2 deletions
|
@ -62,6 +62,7 @@ struct ipa_callback_ops {
|
||||||
|
|
||||||
struct ipa_context_ops {
|
struct ipa_context_ops {
|
||||||
void (*destroy)(struct ipa_context *ctx);
|
void (*destroy)(struct ipa_context *ctx);
|
||||||
|
void *(*get_interface)(struct ipa_context *ctx);
|
||||||
void (*init)(struct ipa_context *ctx);
|
void (*init)(struct ipa_context *ctx);
|
||||||
void (*register_callbacks)(struct ipa_context *ctx,
|
void (*register_callbacks)(struct ipa_context *ctx,
|
||||||
const struct ipa_callback_ops *callbacks,
|
const struct ipa_callback_ops *callbacks,
|
||||||
|
|
|
@ -72,6 +72,13 @@ void IPAInterfaceWrapper::destroy(struct ipa_context *_ctx)
|
||||||
delete 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)
|
void IPAInterfaceWrapper::init(struct ipa_context *_ctx)
|
||||||
{
|
{
|
||||||
IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);
|
IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);
|
||||||
|
@ -228,6 +235,7 @@ void IPAInterfaceWrapper::queueFrameAction(unsigned int frame,
|
||||||
*/
|
*/
|
||||||
const struct ipa_context_ops IPAInterfaceWrapper::operations_ = {
|
const struct ipa_context_ops IPAInterfaceWrapper::operations_ = {
|
||||||
.destroy = &IPAInterfaceWrapper::destroy,
|
.destroy = &IPAInterfaceWrapper::destroy,
|
||||||
|
.get_interface = &IPAInterfaceWrapper::get_interface,
|
||||||
.init = &IPAInterfaceWrapper::init,
|
.init = &IPAInterfaceWrapper::init,
|
||||||
.register_callbacks = &IPAInterfaceWrapper::register_callbacks,
|
.register_callbacks = &IPAInterfaceWrapper::register_callbacks,
|
||||||
.configure = &IPAInterfaceWrapper::configure,
|
.configure = &IPAInterfaceWrapper::configure,
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void destroy(struct ipa_context *ctx);
|
static void destroy(struct ipa_context *ctx);
|
||||||
|
static void *get_interface(struct ipa_context *ctx);
|
||||||
static void init(struct ipa_context *ctx);
|
static void init(struct ipa_context *ctx);
|
||||||
static void register_callbacks(struct ipa_context *ctx,
|
static void register_callbacks(struct ipa_context *ctx,
|
||||||
const struct ipa_callback_ops *callbacks,
|
const struct ipa_callback_ops *callbacks,
|
||||||
|
|
|
@ -33,7 +33,11 @@ private:
|
||||||
struct ipa_operation_data &data);
|
struct ipa_operation_data &data);
|
||||||
static const struct ipa_callback_ops callbacks_;
|
static const struct ipa_callback_ops callbacks_;
|
||||||
|
|
||||||
|
void doQueueFrameAction(unsigned int frame,
|
||||||
|
const IPAOperationData &data);
|
||||||
|
|
||||||
struct ipa_context *ctx_;
|
struct ipa_context *ctx_;
|
||||||
|
IPAInterface *intf_;
|
||||||
|
|
||||||
ControlSerializer serializer_;
|
ControlSerializer serializer_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <libcamera/controls.h>
|
#include <libcamera/controls.h>
|
||||||
|
|
||||||
#include "byte_stream_buffer.h"
|
#include "byte_stream_buffer.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file ipa_context_wrapper.h
|
* \file ipa_context_wrapper.h
|
||||||
|
@ -43,11 +44,19 @@ namespace libcamera {
|
||||||
* with it.
|
* with it.
|
||||||
*/
|
*/
|
||||||
IPAContextWrapper::IPAContextWrapper(struct ipa_context *context)
|
IPAContextWrapper::IPAContextWrapper(struct ipa_context *context)
|
||||||
: ctx_(context)
|
: ctx_(context), intf_(nullptr)
|
||||||
{
|
{
|
||||||
if (!ctx_)
|
if (!ctx_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool forceCApi = !!utils::secure_getenv("LIBCAMERA_IPA_FORCE_C_API");
|
||||||
|
|
||||||
|
if (!forceCApi && ctx_ && ctx_->ops->get_interface) {
|
||||||
|
intf_ = reinterpret_cast<IPAInterface *>(ctx_->ops->get_interface(ctx_));
|
||||||
|
intf_->queueFrameAction.connect(this, &IPAContextWrapper::doQueueFrameAction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ctx_->ops->register_callbacks(ctx_, &IPAContextWrapper::callbacks_,
|
ctx_->ops->register_callbacks(ctx_, &IPAContextWrapper::callbacks_,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +71,9 @@ IPAContextWrapper::~IPAContextWrapper()
|
||||||
|
|
||||||
int IPAContextWrapper::init()
|
int IPAContextWrapper::init()
|
||||||
{
|
{
|
||||||
|
if (intf_)
|
||||||
|
return intf_->init();
|
||||||
|
|
||||||
if (!ctx_)
|
if (!ctx_)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -73,6 +85,9 @@ int IPAContextWrapper::init()
|
||||||
void IPAContextWrapper::configure(const std::map<unsigned int, IPAStream> &streamConfig,
|
void IPAContextWrapper::configure(const std::map<unsigned int, IPAStream> &streamConfig,
|
||||||
const std::map<unsigned int, const ControlInfoMap &> &entityControls)
|
const std::map<unsigned int, const ControlInfoMap &> &entityControls)
|
||||||
{
|
{
|
||||||
|
if (intf_)
|
||||||
|
return intf_->configure(streamConfig, entityControls);
|
||||||
|
|
||||||
if (!ctx_)
|
if (!ctx_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -123,6 +138,9 @@ void IPAContextWrapper::configure(const std::map<unsigned int, IPAStream> &strea
|
||||||
|
|
||||||
void IPAContextWrapper::mapBuffers(const std::vector<IPABuffer> &buffers)
|
void IPAContextWrapper::mapBuffers(const std::vector<IPABuffer> &buffers)
|
||||||
{
|
{
|
||||||
|
if (intf_)
|
||||||
|
return intf_->mapBuffers(buffers);
|
||||||
|
|
||||||
if (!ctx_)
|
if (!ctx_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -148,6 +166,9 @@ void IPAContextWrapper::mapBuffers(const std::vector<IPABuffer> &buffers)
|
||||||
|
|
||||||
void IPAContextWrapper::unmapBuffers(const std::vector<unsigned int> &ids)
|
void IPAContextWrapper::unmapBuffers(const std::vector<unsigned int> &ids)
|
||||||
{
|
{
|
||||||
|
if (intf_)
|
||||||
|
return intf_->unmapBuffers(ids);
|
||||||
|
|
||||||
if (!ctx_)
|
if (!ctx_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -156,6 +177,9 @@ void IPAContextWrapper::unmapBuffers(const std::vector<unsigned int> &ids)
|
||||||
|
|
||||||
void IPAContextWrapper::processEvent(const IPAOperationData &data)
|
void IPAContextWrapper::processEvent(const IPAOperationData &data)
|
||||||
{
|
{
|
||||||
|
if (intf_)
|
||||||
|
return intf_->processEvent(data);
|
||||||
|
|
||||||
if (!ctx_)
|
if (!ctx_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -189,6 +213,12 @@ void IPAContextWrapper::processEvent(const IPAOperationData &data)
|
||||||
ctx_->ops->process_event(ctx_, &c_data);
|
ctx_->ops->process_event(ctx_, &c_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IPAContextWrapper::doQueueFrameAction(unsigned int frame,
|
||||||
|
const IPAOperationData &data)
|
||||||
|
{
|
||||||
|
IPAInterface::queueFrameAction.emit(frame, data);
|
||||||
|
}
|
||||||
|
|
||||||
void IPAContextWrapper::queue_frame_action(void *ctx, unsigned int frame,
|
void IPAContextWrapper::queue_frame_action(void *ctx, unsigned int frame,
|
||||||
struct ipa_operation_data &data)
|
struct ipa_operation_data &data)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +235,7 @@ void IPAContextWrapper::queue_frame_action(void *ctx, unsigned int frame,
|
||||||
opData.controls.push_back(_this->serializer_.deserialize<ControlList>(b));
|
opData.controls.push_back(_this->serializer_.deserialize<ControlList>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
_this->queueFrameAction.emit(frame, opData);
|
_this->doQueueFrameAction(frame, opData);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __DOXYGEN__
|
#ifndef __DOXYGEN__
|
||||||
|
|
|
@ -62,6 +62,12 @@
|
||||||
* handlers to communicate with IPA modules. IPA modules may use the
|
* handlers to communicate with IPA modules. IPA modules may use the
|
||||||
* IPAInterface API internally if they want to benefit from the data and helper
|
* IPAInterface API internally if they want to benefit from the data and helper
|
||||||
* classes offered by libcamera.
|
* classes offered by libcamera.
|
||||||
|
*
|
||||||
|
* When an IPA module is loaded directly into the libcamera process and uses
|
||||||
|
* the IPAInterface API internally, short-circuiting the path to the
|
||||||
|
* ipa_context_ops and back to IPAInterface is desirable. To support this, IPA
|
||||||
|
* modules may implement the ipa_context_ops::get_interface function to return a
|
||||||
|
* pointer to their internal IPAInterface.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,6 +215,18 @@
|
||||||
* \param[in] ctx The IPA context
|
* \param[in] ctx The IPA context
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \var ipa_context_ops::get_interface
|
||||||
|
* \brief Retrieve the IPAInterface implemented by the ipa_context (optional)
|
||||||
|
* \param[in] ctx The IPA context
|
||||||
|
*
|
||||||
|
* IPA modules may implement this function to expose their internal
|
||||||
|
* IPAInterface, if any. When implemented, libcamera may at its sole discretion
|
||||||
|
* call it and then bypass the ipa_context_ops API by calling the IPAInterface
|
||||||
|
* methods directly. IPA modules shall still implement and support the full
|
||||||
|
* ipa_context_ops API.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \var ipa_context_ops::init
|
* \var ipa_context_ops::init
|
||||||
* \brief Initialise the IPA context
|
* \brief Initialise the IPA context
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue