[{"id":12591,"web_url":"https://patchwork.libcamera.org/comment/12591/","msgid":"<20200919124639.GX1850958@oden.dyn.berto.se>","date":"2020-09-19T12:46:39","subject":"Re: [libcamera-devel] [PATCH 22/23] ipa: remove libipa","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Paul,\n\nThanks for your patch.\n\nOn 2020-09-15 23:20:37 +0900, Paul Elder wrote:\n> As every pipeline and have its own proxy, IPAInterfaceWrapper is no\n> longer necessary. Since it's the only member of libipa, remove libipa\n> completely.\n> \n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  src/ipa/libipa/ipa_interface_wrapper.cpp | 285 -----------------------\n>  src/ipa/libipa/ipa_interface_wrapper.h   |  61 -----\n>  src/ipa/libipa/meson.build               |  15 --\n>  src/ipa/meson.build                      |   2 -\n>  src/ipa/raspberrypi/meson.build          |   2 -\n>  src/ipa/raspberrypi/raspberrypi.cpp      |   2 -\n>  6 files changed, 367 deletions(-)\n>  delete mode 100644 src/ipa/libipa/ipa_interface_wrapper.cpp\n>  delete mode 100644 src/ipa/libipa/ipa_interface_wrapper.h\n>  delete mode 100644 src/ipa/libipa/meson.build\n> \n> diff --git a/src/ipa/libipa/ipa_interface_wrapper.cpp b/src/ipa/libipa/ipa_interface_wrapper.cpp\n> deleted file mode 100644\n> index cee532e3..00000000\n> --- a/src/ipa/libipa/ipa_interface_wrapper.cpp\n> +++ /dev/null\n> @@ -1,285 +0,0 @@\n> -/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> -/*\n> - * Copyright (C) 2019, Google Inc.\n> - *\n> - * ipa_interface_wrapper.cpp - Image Processing Algorithm interface wrapper\n> - */\n> -\n> -#include \"ipa_interface_wrapper.h\"\n> -\n> -#include <map>\n> -#include <string.h>\n> -#include <unistd.h>\n> -#include <vector>\n> -\n> -#include <libcamera/ipa/ipa_interface.h>\n> -\n> -#include \"libcamera/internal/byte_stream_buffer.h\"\n> -#include \"libcamera/internal/camera_sensor.h\"\n> -\n> -/**\n> - * \\file ipa_interface_wrapper.h\n> - * \\brief Image Processing Algorithm interface wrapper\n> - */\n> -\n> -namespace libcamera {\n> -\n> -/**\n> - * \\class IPAInterfaceWrapper\n> - * \\brief Wrap an IPAInterface and expose it as an ipa_context\n> - *\n> - * This class implements the ipa_context API based on a provided IPAInterface.\n> - * It helps IPAs that implement the IPAInterface API to provide the external\n> - * ipa_context API.\n> - *\n> - * To use the wrapper, an IPA module simple creates a new instance of its\n> - * IPAInterface implementation, and passes it to the constructor of the\n> - * IPAInterfaceWrapper. As IPAInterfaceWrapper inherits from ipa_context, the\n> - * constructed wrapper can then be directly returned from the IPA module's\n> - * ipaCreate() function.\n> - *\n> - * \\code{.cpp}\n> - * class MyIPA : public IPAInterface\n> - * {\n> - * \t...\n> - * };\n> - *\n> - * struct ipa_context *ipaCreate()\n> - * {\n> - * \treturn new IPAInterfaceWrapper(std::make_unique<MyIPA>());\n> - * }\n> - * \\endcode\n> - *\n> - * The wrapper takes ownership of the IPAInterface and will automatically\n> - * delete it when the wrapper is destroyed.\n> - */\n> -\n> -/**\n> - * \\brief Construct an IPAInterfaceWrapper wrapping \\a interface\n> - * \\param[in] interface The interface to wrap\n> - */\n> -IPAInterfaceWrapper::IPAInterfaceWrapper(std::unique_ptr<IPAInterface> interface)\n> -\t: ipa_(std::move(interface)), callbacks_(nullptr), cb_ctx_(nullptr)\n> -{\n> -\tops = &operations_;\n> -\n> -\tipa_->queueFrameAction.connect(this, &IPAInterfaceWrapper::queueFrameAction);\n> -}\n> -\n> -void IPAInterfaceWrapper::destroy(struct ipa_context *_ctx)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\tdelete ctx;\n> -}\n> -\n> -void *IPAInterfaceWrapper::get_interface(struct ipa_context *_ctx)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\treturn ctx->ipa_.get();\n> -}\n> -\n> -void IPAInterfaceWrapper::init(struct ipa_context *_ctx,\n> -\t\t\t       const struct ipa_settings *settings)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\tIPASettings ipaSettings{\n> -\t\t.configurationFile = settings->configuration_file\n> -\t};\n> -\tctx->ipa_->init(ipaSettings);\n> -}\n> -\n> -int IPAInterfaceWrapper::start(struct ipa_context *_ctx)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\treturn ctx->ipa_->start();\n> -}\n> -\n> -void IPAInterfaceWrapper::stop(struct ipa_context *_ctx)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\tctx->ipa_->stop();\n> -}\n> -\n> -void IPAInterfaceWrapper::register_callbacks(struct ipa_context *_ctx,\n> -\t\t\t\t\t     const struct ipa_callback_ops *callbacks,\n> -\t\t\t\t\t     void *cb_ctx)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\tctx->callbacks_ = callbacks;\n> -\tctx->cb_ctx_ = cb_ctx;\n> -}\n> -\n> -void IPAInterfaceWrapper::configure(struct ipa_context *_ctx,\n> -\t\t\t\t    const struct ipa_sensor_info *sensor_info,\n> -\t\t\t\t    const struct ipa_stream *streams,\n> -\t\t\t\t    unsigned int num_streams,\n> -\t\t\t\t    const struct ipa_control_info_map *maps,\n> -\t\t\t\t    unsigned int num_maps)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\n> -\tctx->serializer_.reset();\n> -\n> -\t/* Translate the IPA sensor info. */\n> -\tCameraSensorInfo sensorInfo{};\n> -\tsensorInfo.model = sensor_info->model;\n> -\tsensorInfo.bitsPerPixel = sensor_info->bits_per_pixel;\n> -\tsensorInfo.activeAreaSize = { sensor_info->active_area.width,\n> -\t\t\t\t      sensor_info->active_area.height };\n> -\tsensorInfo.analogCrop = { sensor_info->analog_crop.left,\n> -\t\t\t\t  sensor_info->analog_crop.top,\n> -\t\t\t\t  sensor_info->analog_crop.width,\n> -\t\t\t\t  sensor_info->analog_crop.height };\n> -\tsensorInfo.outputSize = { sensor_info->output_size.width,\n> -\t\t\t\t  sensor_info->output_size.height };\n> -\tsensorInfo.pixelRate = sensor_info->pixel_rate;\n> -\tsensorInfo.lineLength = sensor_info->line_length;\n> -\n> -\t/* Translate the IPA stream configurations map. */\n> -\tstd::map<unsigned int, IPAStream> ipaStreams;\n> -\n> -\tfor (unsigned int i = 0; i < num_streams; ++i) {\n> -\t\tconst struct ipa_stream &stream = streams[i];\n> -\n> -\t\tipaStreams[stream.id] = {\n> -\t\t\tstream.pixel_format,\n> -\t\t\tSize(stream.width, stream.height),\n> -\t\t};\n> -\t}\n> -\n> -\t/* Translate the IPA entity controls map. */\n> -\tstd::map<unsigned int, const ControlInfoMap &> entityControls;\n> -\tstd::map<unsigned int, ControlInfoMap> infoMaps;\n> -\n> -\tfor (unsigned int i = 0; i < num_maps; ++i) {\n> -\t\tconst struct ipa_control_info_map &ipa_map = maps[i];\n> -\t\tByteStreamBuffer byteStream(ipa_map.data, ipa_map.size);\n> -\t\tunsigned int id = ipa_map.id;\n> -\n> -\t\tinfoMaps[id] = ctx->serializer_.deserialize<ControlInfoMap>(byteStream);\n> -\t\tentityControls.emplace(id, infoMaps[id]);\n> -\t}\n> -\n> -\t/* \\todo Translate the ipaConfig and result. */\n> -\tIPAOperationData ipaConfig;\n> -\tctx->ipa_->configure(sensorInfo, ipaStreams, entityControls, ipaConfig,\n> -\t\t\t     nullptr);\n> -}\n> -\n> -void IPAInterfaceWrapper::map_buffers(struct ipa_context *_ctx,\n> -\t\t\t\t      const struct ipa_buffer *_buffers,\n> -\t\t\t\t      size_t num_buffers)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\tstd::vector<IPABuffer> buffers(num_buffers);\n> -\n> -\tfor (unsigned int i = 0; i < num_buffers; ++i) {\n> -\t\tconst struct ipa_buffer &_buffer = _buffers[i];\n> -\t\tIPABuffer &buffer = buffers[i];\n> -\t\tstd::vector<FrameBuffer::Plane> &planes = buffer.planes;\n> -\n> -\t\tbuffer.id = _buffer.id;\n> -\n> -\t\tplanes.resize(_buffer.num_planes);\n> -\t\tfor (unsigned int j = 0; j < _buffer.num_planes; ++j) {\n> -\t\t\tplanes[j].fd = FileDescriptor(_buffer.planes[j].dmabuf);\n> -\t\t\tplanes[j].length = _buffer.planes[j].length;\n> -\t\t}\n> -\t}\n> -\n> -\tctx->ipa_->mapBuffers(buffers);\n> -}\n> -\n> -void IPAInterfaceWrapper::unmap_buffers(struct ipa_context *_ctx,\n> -\t\t\t\t\tconst unsigned int *_ids,\n> -\t\t\t\t\tsize_t num_buffers)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\tstd::vector<unsigned int> ids(_ids, _ids + num_buffers);\n> -\tctx->ipa_->unmapBuffers(ids);\n> -}\n> -\n> -void IPAInterfaceWrapper::process_event(struct ipa_context *_ctx,\n> -\t\t\t\t\tconst struct ipa_operation_data *data)\n> -{\n> -\tIPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);\n> -\tIPAOperationData opData;\n> -\n> -\topData.operation = data->operation;\n> -\n> -\topData.data.resize(data->num_data);\n> -\tmemcpy(opData.data.data(), data->data,\n> -\t       data->num_data * sizeof(*data->data));\n> -\n> -\topData.controls.resize(data->num_lists);\n> -\tfor (unsigned int i = 0; i < data->num_lists; ++i) {\n> -\t\tconst struct ipa_control_list *c_list = &data->lists[i];\n> -\t\tByteStreamBuffer byteStream(c_list->data, c_list->size);\n> -\t\topData.controls[i] = ctx->serializer_.deserialize<ControlList>(byteStream);\n> -\t}\n> -\n> -\tctx->ipa_->processEvent(opData);\n> -}\n> -\n> -void IPAInterfaceWrapper::queueFrameAction(unsigned int frame,\n> -\t\t\t\t\t   const IPAOperationData &data)\n> -{\n> -\tif (!callbacks_)\n> -\t\treturn;\n> -\n> -\tstruct ipa_operation_data c_data;\n> -\tc_data.operation = data.operation;\n> -\tc_data.data = data.data.data();\n> -\tc_data.num_data = data.data.size();\n> -\n> -\tstruct ipa_control_list control_lists[data.controls.size()];\n> -\tc_data.lists = control_lists;\n> -\tc_data.num_lists = data.controls.size();\n> -\n> -\tstd::size_t listsSize = 0;\n> -\tfor (const auto &list : data.controls)\n> -\t\tlistsSize += serializer_.binarySize(list);\n> -\n> -\tstd::vector<uint8_t> binaryData(listsSize);\n> -\tByteStreamBuffer byteStreamBuffer(binaryData.data(), listsSize);\n> -\n> -\tunsigned int i = 0;\n> -\tfor (const auto &list : data.controls) {\n> -\t\tstruct ipa_control_list &c_list = control_lists[i];\n> -\t\tc_list.size = serializer_.binarySize(list);\n> -\n> -\t\tByteStreamBuffer b = byteStreamBuffer.carveOut(c_list.size);\n> -\t\tserializer_.serialize(list, b);\n> -\n> -\t\tc_list.data = b.base();\n> -\t}\n> -\n> -\tcallbacks_->queue_frame_action(cb_ctx_, frame, c_data);\n> -}\n> -\n> -#ifndef __DOXYGEN__\n> -/*\n> - * This construct confuses Doygen and makes it believe that all members of the\n> - * operations is a member of IPAInterfaceWrapper. It must thus be hidden.\n> - */\n> -const struct ipa_context_ops IPAInterfaceWrapper::operations_ = {\n> -\t.destroy = &IPAInterfaceWrapper::destroy,\n> -\t.get_interface = &IPAInterfaceWrapper::get_interface,\n> -\t.init = &IPAInterfaceWrapper::init,\n> -\t.start = &IPAInterfaceWrapper::start,\n> -\t.stop = &IPAInterfaceWrapper::stop,\n> -\t.register_callbacks = &IPAInterfaceWrapper::register_callbacks,\n> -\t.configure = &IPAInterfaceWrapper::configure,\n> -\t.map_buffers = &IPAInterfaceWrapper::map_buffers,\n> -\t.unmap_buffers = &IPAInterfaceWrapper::unmap_buffers,\n> -\t.process_event = &IPAInterfaceWrapper::process_event,\n> -};\n> -#endif\n> -\n> -} /* namespace libcamera */\n> diff --git a/src/ipa/libipa/ipa_interface_wrapper.h b/src/ipa/libipa/ipa_interface_wrapper.h\n> deleted file mode 100644\n> index a1c70159..00000000\n> --- a/src/ipa/libipa/ipa_interface_wrapper.h\n> +++ /dev/null\n> @@ -1,61 +0,0 @@\n> -/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> -/*\n> - * Copyright (C) 2019, Google Inc.\n> - *\n> - * ipa_interface_wrapper.h - Image Processing Algorithm interface wrapper\n> - */\n> -#ifndef __LIBCAMERA_IPA_INTERFACE_WRAPPER_H__\n> -#define __LIBCAMERA_IPA_INTERFACE_WRAPPER_H__\n> -\n> -#include <memory>\n> -\n> -#include <libcamera/ipa/ipa_interface.h>\n> -\n> -#include \"libcamera/internal/control_serializer.h\"\n> -\n> -namespace libcamera {\n> -\n> -class IPAInterfaceWrapper : public ipa_context\n> -{\n> -public:\n> -\tIPAInterfaceWrapper(std::unique_ptr<IPAInterface> interface);\n> -\n> -private:\n> -\tstatic void destroy(struct ipa_context *ctx);\n> -\tstatic void *get_interface(struct ipa_context *ctx);\n> -\tstatic void init(struct ipa_context *ctx,\n> -\t\t\t const struct ipa_settings *settings);\n> -\tstatic int start(struct ipa_context *ctx);\n> -\tstatic void stop(struct ipa_context *ctx);\n> -\tstatic void register_callbacks(struct ipa_context *ctx,\n> -\t\t\t\t       const struct ipa_callback_ops *callbacks,\n> -\t\t\t\t       void *cb_ctx);\n> -\tstatic void configure(struct ipa_context *ctx,\n> -\t\t\t      const struct ipa_sensor_info *sensor_info,\n> -\t\t\t      const struct ipa_stream *streams,\n> -\t\t\t      unsigned int num_streams,\n> -\t\t\t      const struct ipa_control_info_map *maps,\n> -\t\t\t      unsigned int num_maps);\n> -\tstatic void map_buffers(struct ipa_context *ctx,\n> -\t\t\t\tconst struct ipa_buffer *c_buffers,\n> -\t\t\t\tsize_t num_buffers);\n> -\tstatic void unmap_buffers(struct ipa_context *ctx,\n> -\t\t\t\t  const unsigned int *ids,\n> -\t\t\t\t  size_t num_buffers);\n> -\tstatic void process_event(struct ipa_context *ctx,\n> -\t\t\t\t  const struct ipa_operation_data *data);\n> -\n> -\tstatic const struct ipa_context_ops operations_;\n> -\n> -\tvoid queueFrameAction(unsigned int frame, const IPAOperationData &data);\n> -\n> -\tstd::unique_ptr<IPAInterface> ipa_;\n> -\tconst struct ipa_callback_ops *callbacks_;\n> -\tvoid *cb_ctx_;\n> -\n> -\tControlSerializer serializer_;\n> -};\n> -\n> -} /* namespace libcamera */\n> -\n> -#endif /* __LIBCAMERA_IPA_INTERFACE_WRAPPER_H__ */\n> diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build\n> deleted file mode 100644\n> index 22626405..00000000\n> --- a/src/ipa/libipa/meson.build\n> +++ /dev/null\n> @@ -1,15 +0,0 @@\n> -# SPDX-License-Identifier: CC0-1.0\n> -\n> -libipa_headers = files([\n> -    'ipa_interface_wrapper.h',\n> -])\n> -\n> -libipa_sources = files([\n> -    'ipa_interface_wrapper.cpp',\n> -])\n> -\n> -libipa_includes = include_directories('..')\n> -\n> -libipa = static_library('ipa', libipa_sources,\n> -                        include_directories : ipa_includes,\n> -                        dependencies : libcamera_dep)\n> diff --git a/src/ipa/meson.build b/src/ipa/meson.build\n> index 5a5de267..b11e5d23 100644\n> --- a/src/ipa/meson.build\n> +++ b/src/ipa/meson.build\n> @@ -15,8 +15,6 @@ config_h.set('IPA_CONFIG_DIR',\n>  config_h.set('IPA_MODULE_DIR',\n>               '\"' + join_paths(get_option('prefix'), ipa_install_dir) + '\"')\n>  \n> -subdir('libipa')\n> -\n>  ipa_sign = files('ipa-sign.sh')\n>  \n>  ipas = ['raspberrypi', 'rkisp1', 'vimc']\n> diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build\n> index 9445cd09..e912c668 100644\n> --- a/src/ipa/raspberrypi/meson.build\n> +++ b/src/ipa/raspberrypi/meson.build\n> @@ -10,7 +10,6 @@ rpi_ipa_deps = [\n>  \n>  rpi_ipa_includes = [\n>      ipa_includes,\n> -    libipa_includes,\n>      include_directories('controller')\n>  ]\n>  \n> @@ -46,7 +45,6 @@ mod = shared_module(ipa_name,\n>                      name_prefix : '',\n>                      include_directories : rpi_ipa_includes,\n>                      dependencies : rpi_ipa_deps,\n> -                    link_with : libipa,\n>                      install : true,\n>                      install_dir : ipa_install_dir)\n>  \n> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\n> index e09caa8d..ec04b23d 100644\n> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n> @@ -23,8 +23,6 @@\n>  #include <libcamera/request.h>\n>  #include <libcamera/span.h>\n>  \n> -#include <libipa/ipa_interface_wrapper.h>\n> -\n>  #include \"libcamera/internal/camera_sensor.h\"\n>  #include \"libcamera/internal/log.h\"\n>  #include \"libcamera/internal/utils.h\"\n> -- \n> 2.27.0\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 4CE75C3B5B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 19 Sep 2020 12:46:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1D7EA62FBC;\n\tSat, 19 Sep 2020 14:46:42 +0200 (CEST)","from mail-lj1-x241.google.com (mail-lj1-x241.google.com\n\t[IPv6:2a00:1450:4864:20::241])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 50B2F60367\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 19 Sep 2020 14:46:41 +0200 (CEST)","by mail-lj1-x241.google.com with SMTP id c2so7244758ljj.12\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 19 Sep 2020 05:46:41 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tq22sm1245428lfr.258.2020.09.19.05.46.40\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSat, 19 Sep 2020 05:46:40 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"Jz9UXvce\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=r28StQjUtqOwG0+P4gGmWBStpPGhlHofgD3eskNIh6g=;\n\tb=Jz9UXvce3WA/SDmVdemcRsBc/ZNNqvO4lv9hIZkfkABc08RyiJX4u5rAgTJk6IZkyO\n\to0LqHgVUrDONXmJNyD9hflZHQ7a6jfPIOZFlaGBqW6BOOf8qBPHaTKrxn1WIMlBy6yKU\n\tgjDkK8Gg1yA8DesHyeNPXtRIeMLdBZhXXYK+MMPv1uehU4ZGexWH7thAR+DORfig1SFH\n\t4cCbBUVPnefm7KPHL5gt3x0UHjLPTBBG7cfpzJC5y4xi+rDFmFLfIoh7oPHEFVDYL68o\n\tul86D+v+5pQsEvBOTCCUAfPenzq08p/hFN75UT2Pt08JjrlivkD4r2gQYQazpK+4ARJ7\n\tzqTw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=r28StQjUtqOwG0+P4gGmWBStpPGhlHofgD3eskNIh6g=;\n\tb=cmcNVvEZSfLuM1212cOrrDq5Z2XPDk6TRCvO8v1DIgX7VEC3uo9g42xPvKrfbbvVAC\n\tRik1r+uRFE4w4h0BaLiyzXREhuS+qOxvsZJdWvQOpi3nCLjngRNZRb9Id3t4MF5rm0WL\n\tS16NToSqKXUXLX0PQtmObNW+PjJybfEVALRoPpsw6EsCoC9CgCzV1pxfN9fJ0Ko9cifF\n\tY0UvlKakqkTNtQtTjMtVxsryBMUerO5rZMGPOD1r48GFuhUepGvBfvyl0FJYK5IKRSP+\n\tfINuKwKi5n7a9c+QL8W3Xo+q84vuf89Zm6O+LeM8mzUMS2xC6w3ikm8jkG0V6kUYxbwK\n\tk5CA==","X-Gm-Message-State":"AOAM532ZOcoykhYi0sYeQwCYlRnDxdTzLwtvcyLkXkBEPmhFbHrBVQAM\n\tV+7jHLOH16CBKjV728bdU5rzMw==","X-Google-Smtp-Source":"ABdhPJyQcsGrMSVstIq92/AAspUBqfqzVq2tDT4xr+l8GE4lkwoH3pnnNMNMzEA5Cd4fLSzlLSgT7Q==","X-Received":"by 2002:a2e:a376:: with SMTP id\n\ti22mr12278783ljn.336.1600519600649; \n\tSat, 19 Sep 2020 05:46:40 -0700 (PDT)","Date":"Sat, 19 Sep 2020 14:46:39 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Paul Elder <paul.elder@ideasonboard.com>","Message-ID":"<20200919124639.GX1850958@oden.dyn.berto.se>","References":"<20200915142038.28757-1-paul.elder@ideasonboard.com>\n\t<20200915142038.28757-23-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200915142038.28757-23-paul.elder@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 22/23] ipa: remove libipa","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]