Я новичок в JNI. Почему мой android jni C ++ пытается блокировать исключение? Код вылетает, когда и приложение вылетает без перехода к обработке исключений, это мой код
Activity re code Прием данных H264 с очередью на уровне JAVA Запустить поток декодирования и непрерывно взять кадр пакетов данных H264 из очереди на уровень C ++ для декодирования с помощью FFmpeg
class decode extends Thread {
@Override
public void run() {
// super.run();
while (isDecode) {
byte[] data = one.poll();
if (data != null)
if (ffmpegUtilsInSignalOne != null)
ffmpegUtilsInSignalOne.decodeH264One(data);
}
}
}
cpp Код файла
extern "C"
JNIEXPORT void JNICALL
Java_cn_zhihuiyun_control_utils_FFMPEGUtils_decodeH264One(JNIEnv *env, jobject thiz,
jbyteArray data) {
if (packetOne != nullptr && pCodecCtxOne != nullptr && vFrameOne != nullptr) {
if (data == nullptr)
return;;
if (isPlay == 0)
return;
jbyte *arr = env->GetByteArrayElements(data, JNI_FALSE);
packetOne->data = (uint8_t *) arr;
packetOne->size = env->GetArrayLength(data);
avcodec_send_packet(pCodecCtxOne, packetOne);
avcodec_receive_frame(pCodecCtxOne, vFrameOne);
av_packet_unref(packetOne);
env->ReleaseByteArrayElements(data, arr, 0);
}
}
В это время на уровне C запускается поток отображения для рендеринга экрана
extern "C"
JNIEXPORT void JNICALL
Java_cn_zhihuiyun_control_utils_FFMPEGUtils_initVisThread(JNIEnv *env, jobject thiz) {
isPlay = 1;
threadVister = pthread_create(&threadVister, nullptr,
reinterpret_cast<void *(*)(void *)>(&showVideo),
(void *) env);
pthread_detach(threadVister);
}
void *showVideo(JNIEnv *env) {
try {
while (isPlay == 1) {
if (vFrameOne != nullptr && pFrameRGBAOne != nullptr && pCodecCtxOne != nullptr &&
nativeWindowOne != nullptr) {
ANativeWindow_lock(nativeWindowOne, &windowBufferOne, nullptr);
av_image_fill_arrays(pFrameRGBAOne->data, pFrameRGBAOne->linesize,
(const uint8_t *) windowBufferOne.bits, AV_PIX_FMT_RGBA,
detWidth, detHeight, 1);
int re = -1;
try {
re = libyuv::I420ToARGB(vFrameOne->data[0], vFrameOne->linesize[0],
vFrameOne->data[2], vFrameOne->linesize[2],
vFrameOne->data[1], vFrameOne->linesize[1],
pFrameRGBAOne->data[0], pFrameRGBAOne->linesize[0],
pCodecCtxOne->width, pCodecCtxOne->height);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
} catch (...) {
}
if (re == -1) {
} else {
ANativeWindow_unlockAndPost(nativeWindowOne);
}
}
}
}
} catch (...) {
printf("error");
}
if (vFrameOne != nullptr) {
av_frame_free(&vFrameOne);
vFrameOne = nullptr;
}
if (packetOne != nullptr) {
av_free(packetOne);
packetOne = nullptr;
}
if (pFrameRGBAOne != nullptr) {
av_free(pFrameRGBAOne);
pFrameRGBAOne = nullptr;
}
if (pCodecCtxOne != nullptr) {
avcodec_free_context(&pCodecCtxOne);
pCodecCtxOne = nullptr;
}
if (nativeWindowOne != nullptr) {
ANativeWindow_release(nativeWindowOne);
nativeWindowOne = nullptr;
}
pthread_exit(&threadVister);
}