Запуск этого кода в uithread работает.
Исходный код находится здесь
Я сохраняю собственную ссылку в ByteBuffer, который получает инициализацию при вызове метода INIT() из jni
Java:
Код: Выделить всё
private ByteBuffer nativeHandler = null;
private synchronized static native ByteBuffer INIT();
Код: Выделить всё
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();
}
Код: Выделить всё
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];
}
}
Что я читал о JniEnv, он всегда возвращает контекст из потока, который он запускает. поэтому jnienv должен быть одинаковым для обоих методов, поскольку он вызывается из одного потока.