嗨我试图抓住camerapreview帧并在java后台线程中转换它们从它调用jni方法。 在uithread中运行该代码有效。 来源是here
我将本机引用存储在ByteBuffer中,当从jni调用INIT()方法时它会获取init
爪哇:
didReceiveLocalNotification
JNI:
private ByteBuffer nativeHandler = null;
private synchronized static native ByteBuffer INIT();
当让它在ui线程上运行时,它可以工作
JNIEXPORT jobject JNICALL Java_troop_com_imageconverter_ImageProcessorWrapper_INIT(JNIEnv *env, jobject thiz)
{
ImageProcessor* rgbContainer = new ImageProcessor();
jobject g = env->NewDirectByteBuffer(rgbContainer, 0);
return g;
}
现在将它放在一个java线程中,它会在imageProcessor.ApplyHPF()
上崩溃public void onPreviewFrame(byte[] data, Camera camera)
{
camera.setPreviewCallback(null);
ImageProcessorWrapper imageProcessor = new ImageProcessorWrapper();
imageProcessor.ProcessFrame(data.clone(), w, h);
imageProcessor.ApplyHPF();
}
某种方式第二次调用找不到本机存储的像素数组。 A / libc:致命信号11(SIGSEGV),代码1,故障地址0xa16a8000 in tid 9781(Thread-2246)
private void ProcessOnce(final byte[] _data)
{
new Thread() {
@Override
public void run() {
byte[] data = _data.clone();
try {
final ImageProcessorWrapper imageProcessor = new ImageProcessorWrapper();
if (data != null)
{
imageProcessor.ProcessFrame(data, w, h);
imageProcessor.ApplyHPF(); // that call crash
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
camera.setPreviewCallback(null);
doWork = false;
}
}
}.start();
}
Imageprocessor:
JNIEXPORT void JNICALL Java_troop_com_imageconverter_ImageProcessorWrapper_YUVtoRGB(JNIEnv *env, jobject thiz,jobject handler, jbyteArray yuv420sp, jint width, jint height)
{
jbyte* yuv = (jbyte*) env->GetByteArrayElements(yuv420sp,NULL);
int size = env->GetArrayLength(yuv420sp);
jint* nativeyuv = new jint[size];
ImageProcessor* rgbContainer = (ImageProcessor*)env->GetDirectBufferAddress(handler);
memcpy(nativeyuv,yuv, size);
env->ReleaseByteArrayElements(yuv420sp, yuv, 0);
rgbContainer->YuvToRgb(nativeyuv, width, height);
}
JNIEXPORT void JNICALL Java_troop_com_imageconverter_ImageProcessorWrapper_ApplyHighPassFilter(JNIEnv *env, jobject thiz,jobject handler)
{
ImageProcessor* rgbContainer = (ImageProcessor*)env->GetDirectBufferAddress(handler);
rgbContainer->applyFocusPeak();
}
我的问题是,当从java线程调用它时,如何获得存储本机ImageProcessor的内存区域的vailid引用? 我读到的关于JniEnv的内容总是返回它运行的线程的上下文。因此,两个方法的jnienv应该相等,因为它是从同一个线程调用的。