Passing a ByteBuffer from Java to C++ through JNI

1

Running the SharedCameraAPI. When passing a ByteBuffer through JNI, the app crashes.

2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: Build fingerprint: 'samsung/d2que/d2q:10/QP1A.190711.020/N975U1UES2BTA1:user/release-keys'
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: Revision: '10'
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: ABI: 'arm64'
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: Timestamp: 2020-03-20 23:11:16-0400
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: pid: 7810, tid: 7861, name: sharedCameraBac  >>> com.example.shared_native <<<
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: uid: 10323
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG: signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0x6fb811b060
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x0  000000000000002e  x1  00000070c5927220  x2  0000000000000001  x3  0000000000000049
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x4  0000000000000021  x5  8080800000800000  x6  fefeff6ed0ff4654  x7  7f7f7f7fff7f7f7f
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x8  b3f0189b32adbfe0  x9  b3f0189b32adbfe0  x10 0000006fd2a744a0  x11 0101010101010101
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x12 0000000000000018  x13 ffffffffffffffff  x14 0000000000000000  x15 ffffffffffffffff
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x16 00000070c593a358  x17 00000070c74911bc  x18 0000006fd1b38000  x19 000000702d8d0000
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x20 0000000000000000  x21 000000702d8d0000  x22 0000006fd2a74d00  x23 00000070379c8759
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x24 0000000000000004  x25 0000006fd2a76020  x26 000000702d8d00b0  x27 0000000000000001
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     x28 0000006fd2a74a90  x29 0000006fd2a74a50
2020-03-20 23:11:16.058 7952-7952/? A/DEBUG:     sp  0000006fd2a74a10  lr  0000006fb811b060  pc  0000006fb811b060
2020-03-20 23:11:16.073 7810-7882/com.example.shared_native E/ArCore-Cameras: Failed to extract the metadata or correct the timestamp, status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.076 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.093 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.105 7810-7882/com.example.shared_native E/ArCore-Cameras: Failed to extract the metadata or correct the timestamp, status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.111 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.128 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG: backtrace:
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #00 pc 000000000000d060  /data/app/com.example.shared_native-h2vjpvLs-rSAJ1BRZaMQSA==/lib/arm64/libNativeID3DLib.so (Java_com_example_shared_1native_shared_1camera_SharedCameraLib_getImageBuffer+100) (BuildId: a4f26d3b2bb811326e6db0566a0573bb0f61f84e)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #01 pc 0000000000140350  /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #02 pc 00000000001375b8  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #03 pc 000000000014600c  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #04 pc 00000000002e3d6c  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #05 pc 00000000002defcc  /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+892) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #06 pc 00000000005a495c  /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+372) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #07 pc 0000000000131994  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #08 pc 000000000001989e  [anon:dalvik-classes.dex extracted in memory from /data/app/com.example.shared_native-h2vjpvLs-rSAJ1BRZaMQSA==/base.apk] (com.example.shared_native.shared_camera.SharedCameraActivity.onImageAvailable+70)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #09 pc 00000000005a3968  /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterface+1788) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #10 pc 0000000000131a14  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #11 pc 00000000001f5e88  /system/framework/framework.jar (android.media.ImageReader$ListenerHandler.handleMessage+72)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #12 pc 00000000005a2148  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #13 pc 0000000000131814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #14 pc 000000000035aa86  /system/framework/framework.jar (android.os.Handler.dispatchMessage+38)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #15 pc 00000000005a2148  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #16 pc 0000000000131814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #17 pc 000000000039ae6e  /system/framework/framework.jar (android.os.Looper.loop+466)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #18 pc 00000000005a4bf8  /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1040) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #19 pc 0000000000131994  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #20 pc 000000000035a184  /system/framework/framework.jar (android.os.HandlerThread.run+56)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #21 pc 00000000002b5080  /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.7038959461964381116+240) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #22 pc 00000000005933f0  /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1032) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #23 pc 0000000000140468  /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #24 pc 0000000000137334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #25 pc 0000000000145fec  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #26 pc 00000000004b1884  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #27 pc 00000000004b2998  /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #28 pc 00000000004f38c4  /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176) (BuildId: f14fc1e82182cc00739b366cfefd8688)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #29 pc 00000000000e6f10  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36) (BuildId: 55ce0a7d78144b0290f9746ed1615719)
2020-03-20 23:11:16.133 7952-7952/? A/DEBUG:       #30 pc 00000000000850c8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 55ce0a7d78144b0290f9746ed1615719)
2020-03-20 23:11:16.139 7810-7882/com.example.shared_native E/ArCore-Cameras: Failed to extract the metadata or correct the timestamp, status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.146 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.164 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.182 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.199 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.217 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.235 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.253 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.270 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.287 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.305 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.315 847-2912/? E/AF_DEBUG: [cam_id_0][CMG_EFL] UpdateAfStatus (line 318) : AF status 0x2 0x1
2020-03-20 23:11:16.322 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.339 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.348 847-2911/? E/AF_DEBUG: [CMG_AF_NOTI][cam_id_0] MovieCafPhaseFindGoal(). curr(117), Estgoal(164) OffsetGoal(164)
2020-03-20 23:11:16.357 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.374 7810-7856/com.example.shared_native E/ArCore-Cameras: Metadata for GL texture didn't arrive. camera_id= 0 status= DEADLINE_EXCEEDED: Timed out waiting for metadata
2020-03-20 23:11:16.376 1173-1173/? E//system/bin/tombstoned: Tombstone written to: /data/tombstones/tombstone_05
2020-03-20 23:11:16.383 847-2914/? E/AF_DEBUG: [CMG_AF_NOTI][cam_id_0] MovieCafPhaseFindGoal(). curr(128), Estgoal(168) OffsetGoal(168)
2020-03-20 23:11:16.393 753-753/? E/audit: type=1701 audit(1584760276.385:235403): auid=4294967295 uid=10323 gid=10323 ses=4294967295 subj=u:r:untrusted_app_27:s0:c67,c257,c512,c768 pid=7810 comm="sharedCameraBac" exe="/system/bin/app_process64" sig=5 res=1
2020-03-20 23:11:16.398 1162-1371/? E/system_server: Invalid ID 0x00000000.
2020-03-20 23:11:16.414 847-2914/? E/AF_DEBUG: [CMG_AF_NOTI][cam_id_0] MovieCafPhaseFindGoal(). curr(142), Estgoal(167) OffsetGoal(167)
2020-03-20 23:11:16.428 847-2915/? E/CHI: [SS_ERR ]: [CHI_UNI     ]: camxchinodeUniDepth.cpp: CheckDependency: 708: CheckDependency(0)
2020-03-20 23:11:16.429 1162-1785/? E/InputDispatcher: channel '38ed456 Toast (server)' ~ Channel is unrecoverably broken and will be disposed!
2020-03-20 23:11:16.429 1162-1785/? E/InputDispatcher: channel 'fa09904 com.example.shared_native/com.example.shared_native.shared_camera.SharedCameraActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
2020-03-20 23:11:16.442 1037-1250/? E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -32
2020-03-20 23:11:16.442 1037-1250/? E/Camera3-OutputStream: returnBufferCheckedLocked: Stream 0: Error queueing buffer to native window: Broken pipe (-32)
2020-03-20 23:11:16.442 1037-1250/? E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -32
2020-03-20 23:11:16.442 1037-1250/? E/Camera3-OutputStream: returnBufferCheckedLocked: Stream 1: Error queueing buffer to native window: Broken pipe (-32)
2020-03-20 23:11:16.442 1037-30968/? E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -32
2020-03-20 23:11:16.442 1037-30968/? E/Camera3-OutputStream: returnBufferCheckedLocked: Stream 0: Error queueing buffer to native window: Broken pipe (-32)
2020-03-20 23:11:16.443 1037-7908/? E/Camera3-OutputStream: getBufferLockedCommon: Stream 1: Can't dequeue next output buffer: Broken pipe (-32)
2020-03-20 23:11:16.443 1037-7908/? E/CameraDeviceClient: notifyError: pid=7810, errorCode=3
2020-03-20 23:11:16.443 1037-7859/? E/Camera3-OutputStream: getBufferLockedCommon: Stream 0: Can't dequeue next output buffer: Broken pipe (-32)
2020-03-20 23:11:16.443 1037-7859/? E/CameraDeviceClient: notifyError: pid=7810, errorCode=3
2020-03-20 23:11:16.447 1037-4560/? E/CameraDeviceClient: notifyError: pid=7810, errorCode=0
2020-03-20 23:11:16.447 1037-4560/? E/CameraDeviceClient: Disconnect from CameraDeviceClient

Android Studio 3.6.1 Build #AI-192.7142.36.36.6241897, built on February 27, 2020 Runtime version: 1.8.0_212-release-1586-b4-5784211 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o Linux 5.3.0-42-generic

com.google.ar:core:1.15.0 Samsung Galaxy Note 10+ SM-N975U1

Build fingerprint: 'samsung/d2que/d2q:10/QP1A.190711.020/N975U1UES2BTA1:user/release-keys'

STEPS TO REPRODUCE THE ISSUE

Add ByteBuffer imageBuffer to onAvailableListener method in SharedCameraActivity:

@Override
    public void onImageAvailable(ImageReader imageReader) {
        Image image = imageReader.acquireLatestImage();
        imageBuffer = image.getPlanes()[0].getBuffer().asReadOnlyBuffer();
        if (image == null) {
            Log.w(TAG, "onImageAvailable: Skipping null image.");
            return;
        }
        SharedCameraLib.getImageBuffer(imageBuffer);
        imageBuffer.clear();
        image.close();
    }

Try to read through JNI

 extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_shared_1native_shared_1camera_SharedCameraLib_getImageBuffer(
        JNIEnv *env,
        jclass clazz,
        jobject image_buffer) {
    void* cData = (jbyte *)env->GetDirectBufferAddress(image_buffer);
    LOGI("Image buffer passed successfully.");
}

Edit: I started over with building this native library and here's what it looks like now:

#include <jni.h>
#include <android/log.h>
#include <string>

#define LOG_TAG "example_native"


#ifdef __cplusplus
extern "C" {
#endif

void GetJStringContent(JNIEnv *AEnv, jstring AStr, std::string &ARes) {
  if (!AStr) {
    ARes.clear();
    return;
  }

  const char *s = AEnv->GetStringUTFChars(AStr,NULL);
  ARes=s;
  AEnv->ReleaseStringUTFChars(AStr,s);
}

JNIEXPORT void JNICALL
Java_com_java_sharedcamera_1example_SharedCameraLib_getImageBuffer(
    JNIEnv* env, jobject, jobject image_buffer)
{
    unsigned int *data = (unsigned int*)env->GetDirectBufferAddress(image_buffer);

    for (int i=0; i<10; i++) {
    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "IMAGE BUFFER %d", data[i]);
    }
}

#ifdef __cplusplus
}
#endif

It wasn't working with IntBuffers either, which prompted me to start over with it. Now it's passing the buffer pointer and not crashing.

What is the major difference here? In the first iteration, the JNI was being passed:

JNIEnv *env,
        jclass clazz,
        jobject image_buffer

which I am assuming is related to why it wasn't working? The second iteration was being passed:

JNIEnv* env, 
        jobject, 
        jobject image_buffer

Anytime I've tried to interchange jobject and jclass clazz, it's given an error. When you build a JNI library, what determines whether you end up using jobject and jclass clazz?

java
android
c++
java-native-interface
arcore
asked on Stack Overflow Mar 21, 2020 by jld • edited Mar 21, 2020 by jld

1 Answer

1

You should not call asReadOnlyBuffer(), because it will create a new, read-only byte buffer. The new buffer will have the expected content, but it won't be a DirectByteBuffer anymore, which is what you rely on in your jni code.

answered on Stack Overflow Mar 21, 2020 by Alex Cohn

User contributions licensed under CC BY-SA 3.0