Сбой Jni при вызове из Java BackgroundThread, из основного потока он работаетAndroid

Форум для тех, кто программирует под Android
Anonymous
Сбой Jni при вызове из Java BackgroundThread, из основного потока он работает

Сообщение Anonymous »

Я пытаюсь получить кадры предварительного просмотра камеры и преобразовать их в фоновый поток Java, который вызывает из него методы jni.
Запуск этого кода в uithread работает.
Исходный код находится здесь
Я сохраняю собственную ссылку в ByteBuffer, который получает инициализацию при вызове метода INIT() из jni
Java:

Код: Выделить всё

private ByteBuffer nativeHandler = null;
private synchronized static native ByteBuffer INIT();
jni:

Код: Выделить всё

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;
}
когда запускаем его в потоке пользовательского интерфейса, все работает

Код: Выделить всё

public void onPreviewFrame(byte[] data, Camera camera)
{
camera.setPreviewCallback(null);
ImageProcessorWrapper imageProcessor = new ImageProcessorWrapper();
imageProcessor.ProcessFrame(data.clone(), w, h);
imageProcessor.ApplyHPF();

}
помещая это сейчас в поток Java, происходит сбой при вызове imageProcessor.ApplyHPF()

Код: Выделить всё

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();
}
почему-то второй вызов не находит собственный сохраненный массив пикселей.
A/libc﹕ Фатальный сигнал 11 (SIGSEGV), код 1, адрес ошибки 0xa16a8000 в tid 9781 (Thread-2246)

Код: Выделить всё

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();
}
Обработчик изображений:

Код: Выделить всё

class ImageProcessor {
public:
jint _width;
jint _height;
int* _data;
ImageProcessor()
{
_width = 0;
_height = 0;
_data = new int[0];
}
}
Мой вопрос: как я могу получить действительную ссылку на область памяти, в которой я сохранил собственный ImageProcessor, при вызове его из потока Java?
Что я читал о JniEnv, он всегда возвращает контекст из потока, который он запускает. поэтому jnienv должен быть одинаковым для обоих методов, поскольку он вызывается из одного потока.

Вернуться в «Android»