Hardware Buffer対応#1
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request adds support for decoding AVIF images directly into Android HardwareBuffer objects (RGBA_8888) for both static and animated images, along with corresponding JNI updates, CMake changes, and tests. It also configures the local dav1d build on Android to target 8-bit AV1 only to reduce binary size. The reviewer feedback highlights critical backward-compatibility issues on older Android devices (API < 29 and < 26). Specifically, directly linking nativewindow, calling AHardwareBuffer APIs directly, and referencing HardwareBuffer in AvifDecoder's method signatures will cause runtime crashes or class verification failures on older platforms. To resolve these, it is recommended to dynamically load the native window symbols using dlopen/dlsym and isolate the HardwareBuffer Java APIs into a separate helper class.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| target_link_options(avif_android PRIVATE "-Wl,-z,max-page-size=16384") | ||
| target_link_libraries(avif_android jnigraphics avif log cpufeatures) | ||
| target_link_libraries(avif_android jnigraphics nativewindow avif log cpufeatures) |
There was a problem hiding this comment.
target_link_libraries で nativewindow を直接リンクすると、libavif_android.so に libnativewindow.so へのハード依存関係が導入されます。
libnativewindow.so は Android API 26 (Android 8.0) で導入されたため、Android API < 26 のデバイスで libavif_android.so をロードしようとすると、ハードウェアバッファデコード機能を使用していない場合でも、即座に UnsatisfiedLinkError(例: library "libnativewindow.so" not found)が発生してアプリがクラッシュします。
古い Android バージョンとの後方互換性を維持するために、target_link_libraries から nativewindow を削除し、API レベル 29 以上で実行されている場合にのみ、dlopen を使用して libnativewindow.so を動的にロードし、dlsym を使用して必要な AHardwareBuffer_* シンボルを解決するようにしてください。
target_link_libraries(avif_android jnigraphics avif log cpufeatures)
| if (android_get_device_api_level() < 29) { | ||
| LOGE("HardwareBuffer decode requires API 29+."); | ||
| return nullptr; | ||
| } |
There was a problem hiding this comment.
minSdkVersion が 29 未満でビルドする場合、android_get_device_api_level は <android/api-level.h> 内で弱参照(weak symbol)として宣言されます。
Android API < 29 のデバイスでは、このシンボルは NULL に解決されます。そのため、android_get_device_api_level() を直接呼び出すと、ヌルポインタ参照が発生し、セグメンテーションフォールトでアプリケーションがクラッシュします。
呼び出す前に関数ポインタが非ヌルであることを確認するか、システムプロパティの取得など別の方法で API レベルを判定してください。
if (android_get_device_api_level == nullptr || android_get_device_api_level() < 29) {
LOGE("HardwareBuffer decode requires API 29+.");
return nullptr;
}| AHardwareBuffer_Desc desc = {}; | ||
| desc.width = dst_width; | ||
| desc.height = dst_height; | ||
| desc.layers = 1; | ||
| desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; | ||
| desc.usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY | | ||
| AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; |
There was a problem hiding this comment.
AHardwareBuffer_allocate、AHardwareBuffer_lock、AHardwareBuffer_unlock、AHardwareBuffer_release、および AHardwareBuffer_toHardwareBuffer を直接呼び出すと、API レベル 26〜28(AHardwareBuffer_toHardwareBuffer が未実装)または API < 26(libnativewindow.so が未実装)のデバイスでライブラリをロードする際に UnsatisfiedLinkError が発生します。
これを防ぐため、これらの関数は API レベル 29 以上のデバイスでのみ、dlopen と dlsym を使用して実行時に動的にロードするように実装を変更することを強く推奨します。
| @RequiresApi(29) | ||
| public static HardwareBuffer decodeToHardwareBuffer( | ||
| ByteBuffer encoded, int length, int targetWidth, int targetHeight, int threads) { | ||
| return decodeToHardwareBufferNative(encoded, length, targetWidth, targetHeight, threads); | ||
| } |
There was a problem hiding this comment.
HardwareBuffer クラスは Android API 26 (Android 8.0) で導入されました。
AvifDecoder のメソッドシグネチャ(decodeToHardwareBuffer、nextFrameHardwareBuffer など)に HardwareBuffer を含めると、Android API < 26 のデバイスでクラスの検証(verification)に失敗し、VerifyError または NoClassDefFoundError が発生します。これにより、古いデバイスでは通常の Bitmap デコード機能を含め、AvifDecoder クラス自体のロードが完全に不可能になります。
この問題を回避するために、すべての HardwareBuffer 関連のメソッドを、API >= 29 でのみロードされる別のヘルパークラス(例: AvifHardwareDecoder または遅延ロードされるインナークラス)に移動することを推奨します。これにより、古いデバイスでも AvifDecoder を安全にロードして使用できるようになります。
Feature/hardware buffer r8
No description provided.