Skip to content

docs: add guide for AHB zero-copy input on Android#6733

Open
securekim wants to merge 3 commits into
Tencent:masterfrom
securekim:feature/docs-ahb-zero-copy-example
Open

docs: add guide for AHB zero-copy input on Android#6733
securekim wants to merge 3 commits into
Tencent:masterfrom
securekim:feature/docs-ahb-zero-copy-example

Conversation

@securekim
Copy link
Copy Markdown

Addresses #5531.

The AHB import API (VkAndroidHardwareBufferImageAllocator, VkImageMat::from_android_hardware_buffer, ImportAndroidHardwareBufferPipeline) has no user-facing documentation today and no examples/ entry. The diagnostic context and per-frame measurement data are in the linked issue — short version: users who try the headers against the official prebuilt archive get ld.lld: undefined symbol: ... because build-android.cmd builds with -DANDROID_PLATFORM=android-21, which compiles out every AHB symbol from libncnn.a.

This PR adds a single how-to page (docs/how-to-use-and-FAQ/use-ncnn-with-android-hardware-buffer.md) matching the existing FAQ-ncnn-vulkan.md / vulkan-notes.md style. It covers:

No library or build-system changes. Tested code path on Galaxy S25 Ultra (Adreno 830, Vulkan 1.3.284, NDK r29, ncnn tag 20260113 rebuilt with -DANDROID_PLATFORM=android-26).

Happy to follow up with the examples/ cpp entry as a separate PR if there's interest — held back here because examples/CMakeLists.txt has no precedent for Android-only sources and I didn't want to bundle build-system changes with a docs PR.

Address Tencent#5531 - the AHB import API (VkAndroidHardwareBufferImageAllocator,
ImportAndroidHardwareBufferPipeline) has no user-facing docs today and
existing users hit linker errors against the official prebuilt because
build-android.cmd targets -DANDROID_PLATFORM=android-21 which strips the
AHB symbols.

The new page covers build prerequisites (__ANDROID_API__ >= 26),
AImageReader_newWithUsage setup, the per-frame call sequence, per-AHB-
pointer pipeline caching (~5000x setup-cost reduction), and trouble-
shooting for Tencent#5531 / Tencent#5190.
@github-actions github-actions Bot added the doc label May 21, 2026
@tencent-adm
Copy link
Copy Markdown
Member

CLA assistant check
Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds user-facing documentation for importing Android AHardwareBuffer camera/surface frames into ncnn’s Vulkan path as VkImageMat to enable zero-copy input on Android (addressing #5531).

Changes:

  • Added a new how-to page explaining AHB import prerequisites (notably __ANDROID_API__ >= 26) and the required AImageReader_newWithUsage flags.
  • Documented an end-to-end AHB → VkImageMatVkMat import flow with troubleshooting and caveats.
  • Included guidance on caching ImportAndroidHardwareBufferPipeline to reduce per-frame setup overhead.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/how-to-use-and-FAQ/use-ncnn-with-android-hardware-buffer.md
### troubleshooting

- `ld.lld: undefined symbol: ncnn::VkAndroidHardwareBufferImageAllocator::...` → ncnn was built with `__ANDROID_API__ < 26`. Rebuild ncnn yourself with `-DANDROID_PLATFORM=android-26` or higher; do not rely on the official prebuilt. Symbol-level diagnosis is in [#5531](https://github.com/Tencent/ncnn/issues/5531).
- `VkImageMat::from_android_hardware_buffer` returns an empty mat → check that `AImageReader_newWithUsage` was used (not `AImageReader_new`) and the AHB descriptor actually carries `GPU_SAMPLED_IMAGE` (`desc.usage & 0x100`). [#5190](https://github.com/Tencent/ncnn/issues/5190) is the prior `elemsize`-related bug — fixed in ncnn since.
opt);

ncnn::VkMat dst;
dst.create(width, height, /*c=*/3, /*elemsize=*/4u, /*elempack=*/1, opt.blob_vkallocator);
Comment on lines +79 to +81

**Per-frame `pipe.create` is expensive (~24 ms median on Adreno 830).** The pipeline depends only on the immutable sampler (= the `samplerYcbcrConversion` derived from the AHB's `externalFormat`) and the `(type_to, rotate_from, target_w, target_h)` specialisation constants, all of which are stable for a given camera session. `AImageReader` cycles through a fixed buffer pool (size = `maxImages`), so caching the allocator + pipeline by AHB pointer keeps the cache small (≤ `maxImages` entries) and brings the steady-state setup cost from 24 ms to a few microseconds:

securekim added 2 commits May 22, 2026 16:48
…bound

Two findings from a follow-up spike on Adreno 830:

- ex.input(VkMat) does NOT auto-convert format. The previous draft's hint
  "// ex.input(\"data\", dst, cmd);" actually crashes if the network was
  loaded with use_fp16_storage / use_fp16_packed (common on Vulkan path) -
  NetPrivate::forward_layer recurses on itself looking for an implicit
  converter that doesn't exist, observed as a ~180-frame stack overflow at
  net.cpp:251. Add a dedicated caveat explaining the failure mode and the
  vkdev->convert_packing workaround, and weaken the snippet hint accordingly.

- AImageReader's AHB pool isn't strictly bounded by maxImages. Under steady
  state it stays at maxImages (3 -> 3 cache_n in 36 consecutive cycles), but
  surface/focus events can transiently push it higher (observed cache_n=7
  with maxImages=3 in one run). Soften the "<= maxImages entries" claim.
Same import path verified end-to-end on:
  - Adreno 830, Vulkan 1.3.284 (Galaxy S25 Ultra)
  - Mali-G925 Immortalis MC12, Vulkan 1.3.278 (Galaxy Tab S11)

Both report VK_ANDROID_external_memory_android_hardware_buffer spec
version 5 and surface AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 AHBs from the
camera HAL. Only auxiliary usage bits differ between vendors and are
not consumed by this path (Adreno: 0x20103, Mali: 0x20133).
@nihui
Copy link
Copy Markdown
Member

nihui commented May 22, 2026

@securekim I noticed you're still updating the documentation. Please ping me again once everything is finalized and ready for review :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants