0003-add-Meta-and-starfive-ipa-dummy.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. From 26127511bf0b6d2f016c16956d04332858bd8d7f Mon Sep 17 00:00:00 2001
  2. From: sw.multimedia <sw.multimedia@starfivetech.com>
  3. Date: Thu, 13 Jan 2022 13:52:11 +0800
  4. Subject: [PATCH 03/10] libcamera: 1. add caps for src templ 2. add
  5. starfive ipa (dummy)
  6. ---
  7. include/libcamera/ipa/meson.build | 1 +
  8. include/libcamera/ipa/starfive.mojom | 45 +++++
  9. meson_options.txt | 2 +-
  10. src/gstreamer/gstlibcamerasrc.cpp | 11 +-
  11. src/ipa/starfive/data/meson.build | 8 +
  12. src/ipa/starfive/data/starfive.conf | 3 +
  13. src/ipa/starfive/meson.build | 23 +++
  14. src/ipa/starfive/starfive.cpp | 200 +++++++++++++++++++
  15. src/libcamera/ipa_manager.cpp | 4 +-
  16. src/libcamera/pipeline/starfive/starfive.cpp | 56 +++++-
  17. src/meson.build | 1 +
  18. 11 files changed, 350 insertions(+), 4 deletions(-)
  19. create mode 100644 include/libcamera/ipa/starfive.mojom
  20. create mode 100644 src/ipa/starfive/data/meson.build
  21. create mode 100644 src/ipa/starfive/data/starfive.conf
  22. create mode 100644 src/ipa/starfive/meson.build
  23. create mode 100644 src/ipa/starfive/starfive.cpp
  24. diff --git a/include/libcamera/ipa/meson.build b/include/libcamera/ipa/meson.build
  25. index 6ea94fb5..b84358a6 100644
  26. --- a/include/libcamera/ipa/meson.build
  27. +++ b/include/libcamera/ipa/meson.build
  28. @@ -65,6 +65,7 @@ ipa_mojom_files = [
  29. 'raspberrypi.mojom',
  30. 'rkisp1.mojom',
  31. 'vimc.mojom',
  32. + 'starfive.mojom',
  33. ]
  34. ipa_mojoms = []
  35. diff --git a/include/libcamera/ipa/starfive.mojom b/include/libcamera/ipa/starfive.mojom
  36. new file mode 100644
  37. index 00000000..b302b609
  38. --- /dev/null
  39. +++ b/include/libcamera/ipa/starfive.mojom
  40. @@ -0,0 +1,45 @@
  41. +/* SPDX-License-Identifier: LGPL-2.1-or-later */
  42. +
  43. +/*
  44. + * \todo Document the interface and remove the related EXCLUDE_PATTERNS entry.
  45. + */
  46. +
  47. +module ipa.starfive;
  48. +
  49. +import "include/libcamera/ipa/core.mojom";
  50. +
  51. +const string StarfiveIPAFIFOPath = "/tmp/libcamera_ipa_starfive_fifo";
  52. +
  53. +enum IPAOperationCode {
  54. + IPAOperationNone,
  55. + IPAOperationInit,
  56. + IPAOperationStart,
  57. + IPAOperationStop,
  58. +};
  59. +
  60. +interface IPAStarfiveInterface {
  61. + init(libcamera.IPASettings settings) => (int32 ret);
  62. +
  63. + configure(libcamera.IPACameraSensorInfo sensorInfo,
  64. + map<uint32, libcamera.IPAStream> streamConfig,
  65. + map<uint32, libcamera.ControlInfoMap> entityControls) => (int32 ret);
  66. +
  67. + start() => (int32 ret);
  68. + stop();
  69. +
  70. + mapBuffers(array<libcamera.IPABuffer> buffers);
  71. + unmapBuffers(array<uint32> ids);
  72. +
  73. + /*
  74. + * The starfive driver doesn't use parameters buffers. To maximize coverage
  75. + * of unit tests that rely on the starfive pipeline handler, we still define
  76. + * interface functions that mimick how other pipeline handlers typically
  77. + * handle parameters at runtime.
  78. + */
  79. + [async] fillParams(uint32 frame, uint32 bufferId);
  80. + [async] processControls(uint32 frame, libcamera.ControlList controls);
  81. +};
  82. +
  83. +interface IPAStarfiveEventInterface {
  84. + paramsFilled(uint32 bufferId);
  85. +};
  86. diff --git a/meson_options.txt b/meson_options.txt
  87. index 14baa7ef..ba4ecb0b 100644
  88. --- a/meson_options.txt
  89. +++ b/meson_options.txt
  90. @@ -27,7 +27,7 @@ option('gstreamer',
  91. option('ipas',
  92. type : 'array',
  93. - choices : ['ipu3', 'raspberrypi', 'rkisp1', 'vimc'],
  94. + choices : ['ipu3', 'raspberrypi', 'rkisp1', 'vimc' ,'starfive'],
  95. description : 'Select which IPA modules to build')
  96. option('lc-compliance',
  97. diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
  98. index 1dd0e807..6329b01a 100644
  99. --- a/src/gstreamer/gstlibcamerasrc.cpp
  100. +++ b/src/gstreamer/gstlibcamerasrc.cpp
  101. @@ -140,9 +140,18 @@ G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT,
  102. #define TEMPLATE_CAPS GST_STATIC_CAPS("video/x-raw; image/jpeg")
  103. +#define TEMPLATE_CAPS_SRC GST_STATIC_CAPS("video/x-raw, "\
  104. + "format = { (string)BG24,(string)RG24,(string)BA24, \
  105. + (string)NV12, (string)NV21, (string)NV16, \
  106. + (string)NV61, (string)NV24, (string)UYVY, \
  107. + (string)VYUY, (string)YUYV, (string)YVYU}, "\
  108. + "width = " GST_VIDEO_SIZE_RANGE ", "\
  109. + "height = " GST_VIDEO_SIZE_RANGE ", "\
  110. + "framerate = " GST_VIDEO_FPS_RANGE ";"\
  111. +)
  112. /* For the simple case, we have a src pad that is always present. */
  113. GstStaticPadTemplate src_template = {
  114. - "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS
  115. + "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS_SRC
  116. };
  117. /* More pads can be requested in state < PAUSED */
  118. diff --git a/src/ipa/starfive/data/meson.build b/src/ipa/starfive/data/meson.build
  119. new file mode 100644
  120. index 00000000..0ce6a9b4
  121. --- /dev/null
  122. +++ b/src/ipa/starfive/data/meson.build
  123. @@ -0,0 +1,8 @@
  124. +# SPDX-License-Identifier: CC0-1.0
  125. +
  126. +conf_files = files([
  127. + 'starfive.conf',
  128. +])
  129. +
  130. +install_data(conf_files,
  131. + install_dir : ipa_data_dir / 'starfive')
  132. diff --git a/src/ipa/starfive/data/starfive.conf b/src/ipa/starfive/data/starfive.conf
  133. new file mode 100644
  134. index 00000000..6b74f622
  135. --- /dev/null
  136. +++ b/src/ipa/starfive/data/starfive.conf
  137. @@ -0,0 +1,3 @@
  138. +# SPDX-License-Identifier: LGPL-2.1-or-later
  139. +#
  140. +# Dummy configuration file for the starfive IPA.
  141. diff --git a/src/ipa/starfive/meson.build b/src/ipa/starfive/meson.build
  142. new file mode 100644
  143. index 00000000..c93bd058
  144. --- /dev/null
  145. +++ b/src/ipa/starfive/meson.build
  146. @@ -0,0 +1,23 @@
  147. +# SPDX-License-Identifier: CC0-1.0
  148. +
  149. +ipa_name = 'ipa_starfive'
  150. +
  151. +mod = shared_module(ipa_name,
  152. + ['starfive.cpp', libcamera_generated_ipa_headers],
  153. + name_prefix : '',
  154. + include_directories : [ipa_includes, libipa_includes],
  155. + dependencies : libcamera_private,
  156. + link_with : libipa,
  157. + install : true,
  158. + install_dir : ipa_install_dir)
  159. +
  160. +if ipa_sign_module
  161. + custom_target(ipa_name + '.so.sign',
  162. + input : mod,
  163. + output : ipa_name + '.so.sign',
  164. + command : [ipa_sign, ipa_priv_key, '@INPUT@', '@OUTPUT@'],
  165. + install : false,
  166. + build_by_default : true)
  167. +endif
  168. +
  169. +subdir('data')
  170. diff --git a/src/ipa/starfive/starfive.cpp b/src/ipa/starfive/starfive.cpp
  171. new file mode 100644
  172. index 00000000..e1207606
  173. --- /dev/null
  174. +++ b/src/ipa/starfive/starfive.cpp
  175. @@ -0,0 +1,200 @@
  176. +/* SPDX-License-Identifier: LGPL-2.1-or-later */
  177. +/*
  178. + * Copyright (C) 2019, Google Inc.
  179. + *
  180. + * ipa_starfive.cpp - Starfive Image Processing Algorithm module
  181. + */
  182. +#include <libcamera/ipa/starfive_ipa_interface.h>
  183. +
  184. +#include <fcntl.h>
  185. +#include <string.h>
  186. +#include <sys/stat.h>
  187. +#include <unistd.h>
  188. +
  189. +#include <iostream>
  190. +
  191. +#include <libcamera/base/file.h>
  192. +#include <libcamera/base/log.h>
  193. +
  194. +#include <libcamera/ipa/ipa_interface.h>
  195. +#include <libcamera/ipa/ipa_module_info.h>
  196. +
  197. +#include "libcamera/internal/mapped_framebuffer.h"
  198. +
  199. +namespace libcamera {
  200. +
  201. +LOG_DEFINE_CATEGORY(IPAStarfive)
  202. +
  203. +class IPAStarfive : public ipa::starfive::IPAStarfiveInterface
  204. +{
  205. +public:
  206. + IPAStarfive();
  207. + ~IPAStarfive();
  208. +
  209. + int init(const IPASettings &settings) override;
  210. +
  211. + int start() override;
  212. + void stop() override;
  213. +
  214. + int configure(const IPACameraSensorInfo &sensorInfo,
  215. + const std::map<unsigned int, IPAStream> &streamConfig,
  216. + const std::map<unsigned int, ControlInfoMap> &entityControls) override;
  217. +
  218. + void mapBuffers(const std::vector<IPABuffer> &buffers) override;
  219. + void unmapBuffers(const std::vector<unsigned int> &ids) override;
  220. +
  221. + void fillParams(uint32_t frame, uint32_t bufferId) override;
  222. + void processControls(uint32_t frame, const ControlList &controls) override;
  223. +
  224. +private:
  225. + void initTrace();
  226. + void trace(enum ipa::starfive::IPAOperationCode operation);
  227. +
  228. + int fd_;
  229. + std::map<unsigned int, MappedFrameBuffer> buffers_;
  230. +};
  231. +
  232. +IPAStarfive::IPAStarfive()
  233. + : fd_(-1)
  234. +{
  235. + initTrace();
  236. +}
  237. +
  238. +IPAStarfive::~IPAStarfive()
  239. +{
  240. + if (fd_ != -1)
  241. + ::close(fd_);
  242. +}
  243. +
  244. +int IPAStarfive::init(const IPASettings &settings)
  245. +{
  246. + trace(ipa::starfive::IPAOperationInit);
  247. +
  248. + LOG(IPAStarfive, Debug)
  249. + << "initializing starfive IPA with configuration file "
  250. + << settings.configurationFile;
  251. +
  252. + File conf(settings.configurationFile);
  253. + if (!conf.open(File::OpenModeFlag::ReadOnly)) {
  254. + LOG(IPAStarfive, Error) << "Failed to open configuration file";
  255. + return -EINVAL;
  256. + }
  257. +
  258. + return 0;
  259. +}
  260. +
  261. +int IPAStarfive::start()
  262. +{
  263. + trace(ipa::starfive::IPAOperationStart);
  264. +
  265. + LOG(IPAStarfive, Debug) << "start starfive IPA!";
  266. +
  267. + return 0;
  268. +}
  269. +
  270. +void IPAStarfive::stop()
  271. +{
  272. + trace(ipa::starfive::IPAOperationStop);
  273. +
  274. + LOG(IPAStarfive, Debug) << "stop starfive IPA!";
  275. +}
  276. +
  277. +int IPAStarfive::configure([[maybe_unused]] const IPACameraSensorInfo &sensorInfo,
  278. + [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig,
  279. + [[maybe_unused]] const std::map<unsigned int, ControlInfoMap> &entityControls)
  280. +{
  281. + LOG(IPAStarfive, Debug) << "configure()";
  282. +
  283. + return 0;
  284. +}
  285. +
  286. +void IPAStarfive::mapBuffers(const std::vector<IPABuffer> &buffers)
  287. +{
  288. + LOG(IPAStarfive, Debug) << "mapBuffers()";
  289. + for (const IPABuffer &buffer : buffers) {
  290. + const FrameBuffer fb(buffer.planes);
  291. + buffers_.emplace(std::piecewise_construct,
  292. + std::forward_as_tuple(buffer.id),
  293. + std::forward_as_tuple(&fb, MappedFrameBuffer::MapFlag::Read));
  294. + }
  295. +}
  296. +
  297. +void IPAStarfive::unmapBuffers(const std::vector<unsigned int> &ids)
  298. +{
  299. + LOG(IPAStarfive, Debug) << "unmapBuffers()";
  300. + for (unsigned int id : ids) {
  301. + auto it = buffers_.find(id);
  302. + if (it == buffers_.end())
  303. + continue;
  304. +
  305. + buffers_.erase(it);
  306. + }
  307. +}
  308. +
  309. +void IPAStarfive::fillParams([[maybe_unused]] uint32_t frame, uint32_t bufferId)
  310. +{
  311. + auto it = buffers_.find(bufferId);
  312. + if (it == buffers_.end()) {
  313. + LOG(IPAStarfive, Error) << "Could not find parameter buffer";
  314. + return;
  315. + }
  316. +
  317. + paramsFilled.emit(bufferId);
  318. +}
  319. +
  320. +void IPAStarfive::processControls([[maybe_unused]] uint32_t frame,
  321. + [[maybe_unused]] const ControlList &controls)
  322. +{
  323. + LOG(IPAStarfive,Debug) << "IPA ProcessControl";
  324. +}
  325. +
  326. +void IPAStarfive::initTrace()
  327. +{
  328. + struct stat fifoStat;
  329. + int ret = stat(ipa::starfive::StarfiveIPAFIFOPath.c_str(), &fifoStat);
  330. + if (ret)
  331. + return;
  332. +
  333. + ret = ::open(ipa::starfive::StarfiveIPAFIFOPath.c_str(), O_WRONLY);
  334. + if (ret < 0) {
  335. + ret = errno;
  336. + LOG(IPAStarfive, Error) << "Failed to open starfive IPA test FIFO: "
  337. + << strerror(ret);
  338. + return;
  339. + }
  340. +
  341. + fd_ = ret;
  342. +}
  343. +
  344. +void IPAStarfive::trace(enum ipa::starfive::IPAOperationCode operation)
  345. +{
  346. + if (fd_ < 0)
  347. + return;
  348. +
  349. + int ret = ::write(fd_, &operation, sizeof(operation));
  350. + if (ret < 0) {
  351. + ret = errno;
  352. + LOG(IPAStarfive, Error) << "Failed to write to starfive IPA test FIFO: "
  353. + << strerror(ret);
  354. + }
  355. +}
  356. +
  357. +/*
  358. + * External IPA module interface
  359. + */
  360. +
  361. +extern "C" {
  362. +const struct IPAModuleInfo ipaModuleInfo = {
  363. + IPA_MODULE_API_VERSION,
  364. + 0,
  365. + "PipelineHandlerStarFive",
  366. + "starfive",
  367. +};
  368. +
  369. +IPAInterface *ipaCreate()
  370. +{
  371. + return new IPAStarfive();
  372. +}
  373. +}
  374. +
  375. +} /* namespace libcamera */
  376. diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
  377. index ec966045..634cbb8d 100644
  378. --- a/src/libcamera/ipa_manager.cpp
  379. +++ b/src/libcamera/ipa_manager.cpp
  380. @@ -276,7 +276,9 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,
  381. bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
  382. {
  383. -#if HAVE_IPA_PUBKEY
  384. +#if SKIP_SIGN_VERIFY
  385. + return true;
  386. +#elif HAVE_IPA_PUBKEY
  387. char *force = utils::secure_getenv("LIBCAMERA_IPA_FORCE_ISOLATION");
  388. if (force && force[0] != '\0') {
  389. LOG(IPAManager, Debug)
  390. diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
  391. index f63af910..bc82a062 100644
  392. --- a/src/libcamera/pipeline/starfive/starfive.cpp
  393. +++ b/src/libcamera/pipeline/starfive/starfive.cpp
  394. @@ -23,6 +23,10 @@
  395. #include <linux/videodev2.h>
  396. #include <linux/v4l2-subdev.h>
  397. +#include <libcamera/ipa/ipa_interface.h>
  398. +#include <libcamera/ipa/ipa_module_info.h>
  399. +#include <libcamera/ipa/starfive_ipa_interface.h>
  400. +#include <libcamera/ipa/starfive_ipa_proxy.h>
  401. #include "libcamera/internal/camera.h"
  402. #include "libcamera/internal/camera_sensor.h"
  403. #include "libcamera/internal/device_enumerator.h"
  404. @@ -189,6 +193,7 @@ public:
  405. std::vector<SizeRange> sensorSizes() const;
  406. std::vector<PixelFormat> sensorFormats() const;
  407. std::vector<PixelFormat> videoFormats() const;
  408. + void paramsFilled(unsigned int id){}
  409. MediaDevice *media_;
  410. V4L2VideoDevice *video_;
  411. @@ -197,6 +202,8 @@ public:
  412. CameraSensor *sensor_;
  413. Stream outStream_;
  414. Stream rawStream_;
  415. + std::unique_ptr<ipa::starfive::IPAProxyStarfive> ipa_;
  416. + std::vector<std::unique_ptr<FrameBuffer>> mockIPABufs_;
  417. private:
  418. bool haveRaw_;
  419. @@ -591,6 +598,22 @@ int PipelineHandlerStarFive::configure(Camera *camera, CameraConfiguration *c)
  420. data->video_->toV4L2PixelFormat(cfg.pixelFormat))
  421. return -EINVAL;
  422. }
  423. +
  424. + if (data->ipa_) {
  425. + /* Inform IPA of stream configuration and sensor controls. */
  426. + std::map<unsigned int, IPAStream> streamConfig;
  427. + streamConfig.emplace(std::piecewise_construct,
  428. + std::forward_as_tuple(0),
  429. + std::forward_as_tuple(cfg.pixelFormat, cfg.size));
  430. +
  431. + std::map<unsigned int, ControlInfoMap> entityControls;
  432. + entityControls.emplace(0, data->sensor_->controls());
  433. +
  434. + IPACameraSensorInfo sensorInfo;
  435. + data->sensor_->sensorInfo(&sensorInfo);
  436. +
  437. + data->ipa_->configure(sensorInfo, streamConfig, entityControls);
  438. + }
  439. }
  440. return 0;
  441. @@ -630,6 +653,17 @@ int PipelineHandlerStarFive::start(Camera *camera, const ControlList *controls)
  442. ret = data->video_->importBuffers(count);
  443. if (ret < 0)
  444. return ret;
  445. +
  446. + /* Map the mock IPA buffers to VIMC IPA to exercise IPC code paths. */
  447. + std::vector<IPABuffer> ipaBuffers;
  448. + for (auto [i, buffer] : utils::enumerate(data->mockIPABufs_)) {
  449. + buffer->setCookie(i + 1);
  450. + ipaBuffers.emplace_back(buffer->cookie(), buffer->planes());
  451. + }
  452. + data->ipa_->mapBuffers(ipaBuffers);
  453. + ret = data->ipa_->start();
  454. + if(ret < 0)
  455. + goto error;
  456. ret = data->video_->streamOn();
  457. if (ret < 0)
  458. @@ -661,6 +695,7 @@ int PipelineHandlerStarFive::start(Camera *camera, const ControlList *controls)
  459. return ret;
  460. error:
  461. + data->ipa_->stop();
  462. data->video_->releaseBuffers();
  463. return ret;
  464. }
  465. @@ -671,6 +706,12 @@ void PipelineHandlerStarFive::stop(Camera *camera)
  466. StarFiveCameraData *data = cameraData(camera);
  467. data->video_->streamOff();
  468. + std::vector<unsigned int> ids;
  469. + for (const std::unique_ptr<FrameBuffer> &buffer : data->mockIPABufs_)
  470. + ids.push_back(buffer->cookie());
  471. + data->ipa_->unmapBuffers(ids);
  472. + data->ipa_->stop();
  473. +
  474. data->video_->releaseBuffers();
  475. if (data->rawActive()) {
  476. data->raw_->streamOff();
  477. @@ -813,8 +854,11 @@ int PipelineHandlerStarFive::queueRequestDevice(Camera *camera, Request *request
  478. LOG(STARFIVE, Debug)
  479. << "stream queueBuffer : " << stream->configuration().toString();
  480. - if (stream == &data->outStream_)
  481. + if (stream == &data->outStream_){
  482. ret = data->video_->queueBuffer(buffer);
  483. + data->ipa_->processControls(request->sequence(), request->controls());
  484. + }
  485. +
  486. else if (stream == &data->rawStream_)
  487. ret = data->raw_->queueBuffer(buffer);
  488. else
  489. @@ -918,6 +962,16 @@ int PipelineHandlerStarFive::registerCameras()
  490. if (data->init())
  491. continue;
  492. + /*create ipa module*/
  493. + data->ipa_ = IPAManager::createIPA<ipa::starfive::IPAProxyStarfive>(this, 0, 0);
  494. + if (!data->ipa_) {
  495. + LOG(STARFIVE, Error) << "no matching IPA found";
  496. + return false;
  497. + }
  498. + data->ipa_->paramsFilled.connect(data.get(), &StarFiveCameraData::paramsFilled);
  499. + std::string conf = data->ipa_->configurationFile("starfive.conf");
  500. + data->ipa_->init(IPASettings{ conf, data->sensor_->model() });
  501. +
  502. /* Create and register the camera. */
  503. LOG(STARFIVE, Debug) << "register deviceName: "
  504. << videoEntiryName;
  505. diff --git a/src/meson.build b/src/meson.build
  506. index e0ea9c35..8ae89b5b 100644
  507. --- a/src/meson.build
  508. +++ b/src/meson.build
  509. @@ -20,6 +20,7 @@ if openssl.found()
  510. output : ['ipa-priv-key.pem'],
  511. command : [gen_ipa_priv_key, '@OUTPUT@'])
  512. config_h.set('HAVE_IPA_PUBKEY', 1)
  513. + config_h.set('SKIP_SIGN_VERIFY',1)
  514. ipa_sign_module = true
  515. else
  516. ipa_sign_module = false
  517. --
  518. 2.25.1