Skip to content

package/majestic-af: build the out-of-core autofocus plugin from source - #2357

Merged
widgetii merged 4 commits into
masterfrom
majestic-af-package
Sep 3, 2026
Merged

package/majestic-af: build the out-of-core autofocus plugin from source#2357
widgetii merged 4 commits into
masterfrom
majestic-af-package

Conversation

@widgetii

@widgetii widgetii commented Sep 3, 2026

Copy link
Copy Markdown
Member

Problem

majestic's autofocus engine moved out of the core binary into the open-source
OpenIPC/majestic-af plugin
(widgetii/majestic#553). Nothing in firmware builds or ships that plugin, so the
engine is unavailable. This adds a Buildroot package that compiles it from
source
(like motors) and selects it for hi3516ev300_lite, so the 85H50AI
board — whose builder profile enables autofocus (OpenIPC/builder#142) — gets
working autofocus out of the box.

Hardware tested on

hi3516ev300 + XiongMai 85H50AI (motorized 2.8–12 mm lens) — the board the
engine was developed and proven on.

Evidence

The .so from this package was built and installed into a real image by the
builder companion (OpenIPC/builder#145): its full hi3516ev300_lite_xm-85h50ai
device firmware build compiled majestic-af.so from source and installed it —
passed (5m18s).

Runtime behaviour was validated on the target with the same sources + same
hi3516ev200 toolchain during widgetii/majestic#553:

Before (no plugin .so):

GET /autofocus        -> unavailable        (majestic keeps running normally)

After (/usr/lib/majestic-af.so present, autofocus enabled):

GET /autofocus        -> done fv=9520 peak=9520 mag=-1.0 pos=20 path=2   # cold focus
GET /zoom?tele        -> zooming
GET /autofocus/status -> done fv=9716 peak=10104 mag=1.7 pos=1280        # zoom + refocus
GET /zoom             -> mag=1.7 age_ms=...                              # magnification -> OSD
kill -HUP <pid> mid-pass -> same pid alive, no crash, AF works after reload

Scope

  • No kernel patches under general/package/all-patches/linux/
  • No files specific to a single retail camera model (the package is generic; the board selection is a one-line generic-SoC defconfig — the device profile lives in OpenIPC/builder)
  • No probing or bring-up tooling
  • Nothing under general/overlay/ or a shared load_<vendor> hardcodes a board value
  • Package sources come from an OpenIPC repository (OpenIPC/majestic-af), pinned to a full 40-character SHA
  • No LD_PRELOAD, and no binaries that cannot be rebuilt from source (compiled from source here)
  • New code is selected by a defconfig (hi3516ev300_lite), so CI builds it

majestic's autofocus engine now lives out of core in the OpenIPC/majestic-af
plugin — a single shared object majestic dlopen()s. Compile it from source the
way motors is: fetch the repo, build plugin.c/engine.c/af2.c into majestic-af.so,
install to /usr/lib. The HAL seams it calls (sdk_get_focus_value, ...) resolve
against the majestic executable at dlopen (majestic built WITH_PLUGINS_SUPPORT),
so it links nothing from majestic — only its own vendored headers.

depends on BR2_PACKAGE_MAJESTIC; a board's defconfig selects it (the hi3516ev300
85H50AI profile does), and the engine only loads where autofocus is enabled, so
shipping the .so where it isn't used is harmless.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Build Majestic autofocus plugin from source

✨ Enhancement ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Registers an optional Buildroot package for Majestic’s out-of-core autofocus engine.
• Cross-compiles autofocus sources into a runtime-loaded shared object.
• Installs the plugin under /usr/lib for selected device profiles.
Diagram

graph TD
  A["Board selection"] --> B["Package config"] --> C["Build recipe"] --> D["AF plugin"] --> E["Majestic runtime"]
  F["GitHub source"] --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pin an immutable revision
  • ➕ Makes firmware builds reproducible.
  • ➕ Prevents unreviewed upstream changes from entering builds.
  • ➖ Requires explicit version bumps for autofocus fixes.
  • ➖ Does not automatically track the latest plugin source.
2. Bundle the plugin with Majestic
  • ➕ Keeps the plugin and exported runtime ABI in lockstep.
  • ➕ Reduces the chance of source and binary incompatibility.
  • ➖ Couples an open-source plugin to the proprietary Majestic artifact.
  • ➖ Removes independent board-level package selection.
  • ➖ Prevents Buildroot from compiling the plugin directly from source.

Recommendation: Keep the independent generic-package approach: it preserves board-level opt-in, source visibility, and separation from the Majestic binary. Prefer an immutable commit or release over HEAD when a stable revision is available to ensure reproducible firmware builds.

Files changed (3) +43 / -0

Enhancement (1) +11 / -0
Config.inDefine the optional Majestic autofocus package +11/-0

Define the optional Majestic autofocus package

• Introduces the 'BR2_PACKAGE_MAJESTIC_AF' option with a dependency on Majestic. Documents runtime loading, autofocus behavior, and supported motorized-lens protocols.

general/package/majestic-af/Config.in

Other (2) +32 / -0
Config.inRegister the Majestic autofocus package +1/-0

Register the Majestic autofocus package

• Adds the Majestic autofocus package configuration to the general Buildroot package menu.

general/package/Config.in

majestic-af.mkCross-compile and install the autofocus plugin +31/-0

Cross-compile and install the autofocus plugin

• Fetches OpenIPC/majestic-af, compiles its three C sources into 'majestic-af.so', and installs it under '/usr/lib'. The recipe intentionally leaves Majestic HAL symbols unresolved for runtime binding.

general/package/majestic-af/majestic-af.mk

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. majestic-af lacks hardware evidence 📘 Rule violation ☼ Reliability
Description
The package installs a runtime-loaded autofocus/PTZ plugin whose unresolved HAL calls, actuator
threads, focus sampling, and motor control can change camera behavior, but the PR provides only
compilation and ELF/shared-object validation. Real-camera before/after evidence is required to
establish successful dlopen, HAL resolution, boot and streaming operation, autofocus convergence,
and motorized-lens actuation on the affected target hardware.
Code

general/package/majestic-af/majestic-af.mk[28]

+	$(INSTALL) -m 0644 -D $(@D)/majestic-af.so $(TARGET_DIR)/usr/lib/majestic-af.so
Evidence
PR Compliance ID 1 requires real-camera evidence for changes that can alter camera behavior. The
package installs the shared object into the target root filesystem and documents runtime resolution
against Majestic, while its help text confirms that it runs autofocus, motorized-lens actuation, and
worker threads when enabled; therefore successful compilation, ELF construction, and symbol
inspection do not exercise or demonstrate the image and camera behavior introduced by these lines.

Rule 1: Hardware evidence is present and honest
general/package/majestic-af/majestic-af.mk[27-28]
general/package/majestic-af/Config.in[5-9]
general/package/majestic-af/majestic-af.mk[13-18]
general/package/majestic-af/majestic-af.mk[27-29]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
This image-affecting autofocus/PTZ plugin has only build-time and ELF-level verification; provide target-camera evidence showing that it loads correctly and that its autofocus and motor-control behavior works without disrupting normal camera operation.
## Issue Context
Run a before/after hardware test on the intended `hi3516ev300_lite_xm-85h50ai` device. Record camera boot and Majestic startup/plugin-load output, demonstrate successful streaming, autofocus activation and motor movement, verify focus convergence, and confirm Majestic remains operational when autofocus is disabled or plugin loading fails.
## Fix Focus Areas
- general/package/majestic-af/majestic-af.mk[13-18]
- general/package/majestic-af/majestic-af.mk[27-29]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. MAJESTIC_AF lacks defconfig selection ✓ Resolved 📘 Rule violation ≡ Correctness
Description
The new buildable package is not selected by any defconfig in this branch, so repository CI will not
compile or install it. A companion PR outside this change does not wire the package into the build
being reviewed.
Code

general/package/majestic-af/Config.in[R1-3]

+config BR2_PACKAGE_MAJESTIC_AF
+	bool "majestic-af"
+	depends on BR2_PACKAGE_MAJESTIC
Evidence
PR Compliance ID 2 requires at least one defconfig to select newly integrated source packages. The
diff defines and builds BR2_PACKAGE_MAJESTIC_AF, but no defconfig in the PR branch contains that
symbol.

Rule 2: New sources are wired into the build
general/package/majestic-af/Config.in[1-3]
general/package/majestic-af/majestic-af.mk[19-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `BR2_PACKAGE_MAJESTIC_AF` package is not selected by any defconfig in this branch, leaving its build untested by repository CI.
## Issue Context
The package has a `Config.in` definition and build/install rules, but a repository-wide search found no defconfig selecting `BR2_PACKAGE_MAJESTIC_AF`. Add the selection to an appropriate supported defconfig without introducing board-specific values into shared configuration.
## Fix Focus Areas
- general/package/majestic-af/Config.in[1-3]
- br-ext-chip-hisilicon/configs/hi3516ev300_lite_defconfig[58-58]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Mutable source revision ✓ Resolved 🐞 Bug ☼ Reliability
Description
The package fetches GitHub HEAD, so identical firmware inputs can compile different plugin code as
the branch advances or is rewritten. This prevents reproducible builds and leaves deployed images
without an immutable source provenance.
Code

general/package/majestic-af/majestic-af.mk[8]

+MAJESTIC_AF_VERSION = HEAD
Evidence
The GitHub download URL is constructed directly from MAJESTIC_AF_VERSION, which the new package
sets to mutable HEAD rather than a commit or tag.

general/package/majestic-af/majestic-af.mk[7-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The majestic-af package uses the mutable `HEAD` revision, making builds non-reproducible and allowing source contents to change without a firmware commit.
## Issue Context
The OpenIPC repository URL is appropriate, but the package version must be an immutable full 40-character commit SHA or a stable tag.
## Fix Focus Areas
- general/package/majestic-af/majestic-af.mk[7-8]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Unsupported binaries remain selectable 🐞 Bug ≡ Correctness
Description
BR2_PACKAGE_MAJESTIC_AF depends only on Majestic even though its shared object explicitly requires
a Majestic binary exporting the plugin HAL symbols. A non-plugin Majestic binary satisfies this
dependency but cannot load the installed autofocus plugin, leaving the selected feature silently
nonfunctional.
Code

general/package/majestic-af/Config.in[3]

+	depends on BR2_PACKAGE_MAJESTIC
Evidence
The new package's own build comments state that loading requires WITH_PLUGINS_SUPPORT, while the
Majestic package chooses opaque prebuilt archives using only family and variant and exposes no
corresponding Kconfig guarantee.

general/package/majestic-af/majestic-af.mk[13-18]
general/package/majestic-af/Config.in[1-3]
general/package/majestic/majestic.mk[7-13]
general/package/majestic/Config.in[1-5]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Kconfig dependency permits majestic-af with Majestic binaries that do not export the symbols required at `dlopen()` time.
## Issue Context
Majestic is selected as a prebuilt archive by SoC family and variant, and its package exposes no plugin-support capability symbol. Restrict majestic-af to known compatible binaries or introduce a capability symbol that compatible Majestic configurations select.
## Fix Focus Areas
- general/package/majestic-af/Config.in[1-3]
- general/package/majestic-af/majestic-af.mk[13-18]
- general/package/majestic/majestic.mk[7-13]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can add REVIEW.md to your repo root and Qodo follows it on every PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread general/package/majestic-af/majestic-af.mk
Comment thread general/package/majestic-af/Config.in
Comment thread general/package/majestic-af/majestic-af.mk Outdated
Comment thread general/package/majestic-af/Config.in
…are board

The selector requires every general/package to be built by some board in
ALL_BOARDS or listed in NOT_BUILT. majestic-af's BR2_PACKAGE selection lives in
the OpenIPC/builder device defconfig (hi3516ev300_lite_xm-85h50ai), so no
firmware defconfig builds it — add it to NOT_BUILT, like matter and the other
device/overlay-selected packages.
@widgetii

widgetii commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

Thanks — responses to the review:

  1. Hardware evidence — the engine was validated extensively on this exact board (hi3516ev300 + 85H50AI) as part of widgetii/majestic#553: cold focus, zoom-then-refocus, magnification to the OSD, and a mid-pass config-reload (SIGHUP) with clean thread teardown, no crash. The builder companion PR (xm-85h50ai: ship the majestic-af autofocus plugin builder#145) runs the full device firmware build.

  2. No defconfig selection / 4. selectable without plugin support — this is deliberate. majestic-af is a device-specific package: its BR2_PACKAGE_MAJESTIC_AF=y lives in the OpenIPC/builder device defconfig (hi3516ev300_lite_xm-85h50ai), which builds and CI-tests it there — hence NOT_BUILT here, like the other overlay/device-selected packages. There is no Kconfig symbol for "majestic built with plugin-symbol export": that's a property of the per-family S3 build (this board's hi3516ev200-family majestic is compiled WITH_PLUGINS_SUPPORT), so it can't be a depends on. If the seams aren't exported the plugin's dlopen simply fails and majestic runs without autofocus — it degrades, it doesn't break.

  3. Mutable HEAD — intentional and consistent with motors (the package this is modeled on), which also tracks HEAD so testers get the latest. I'll pin to a tag once the plugin cuts its first release.

Per PR-compliance rule 2 (new sources wired into the build) a defconfig must
select the package, and rule ('one board, one file') prefers a generic SoC
defconfig over device-only selection. hi3516ev300_lite is the hi3516ev200-family
build whose majestic is compiled WITH_PLUGINS_SUPPORT, so the plugin's HAL seams
resolve at dlopen there. Selecting it here builds and installs it under firmware
CI; drop the ci-matrix NOT_BUILT exception accordingly. The .so only loads where
isp.autofocus is enabled, so shipping it on other ev300-lite images is harmless.
PR-compliance: a new package should pin a full 40-character SHA for reproducible
builds. Bump this when the plugin cuts fixes/releases.
@widgetii
widgetii merged commit 347335a into master Sep 3, 2026
117 checks passed
@widgetii
widgetii deleted the majestic-af-package branch September 3, 2026 06:15
widgetii added a commit to OpenIPC/builder that referenced this pull request Sep 3, 2026
)

Select BR2_PACKAGE_MAJESTIC_AF in the device defconfig so the test board's firmware carries /usr/lib/majestic-af.so out of the box. The package is defined in the firmware external tree (OpenIPC/firmware#2357, merged first); builder.sh clones firmware master, and the device build compiles the plugin from source (7caebdc6) and installs it — verified end-to-end in CI after the firmware merge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant