Android — я пытаюсь изменить байтовый массив и отправить его из C ++ в Java через JNI

Это моя функция:

void FrameReceived(int width, int height, const char *rawImageBytes, int size, jboolean remote)
{

if(size == 0)
return;

jboolean isAttached;
JNIEnv *env;
jint jParticipant;
jint jWidth;
jint jHeight;
jbyte *jRawImageBytes;
jbyte *modifiedRawImageBytes;
jbyteArray Array;

env = getJniEnv(&isAttached);

if (env == NULL)
goto FAIL0;
//LOGE(".... **** ....TRYING TO FIND CALLBACK");
if(remote)
{
if(frameReceivedRemoteMethod == NULL)
frameReceivedRemoteMethod = getApplicationJniMethodId(env, applicationJniObj, "vidyoConferenceFrameReceivedRemoteCallback", "(III[B)V");

if (frameReceivedRemoteMethod == NULL) {
//LOGE(".... **** ....CALLBACK NOT FOUND");
goto FAIL1;
}
}
else
{
if(frameReceivedMethod == NULL)
frameReceivedMethod = getApplicationJniMethodId(env, applicationJniObj, "vidyoConferenceFrameReceivedCallback", "(III[B)V");

if (frameReceivedMethod == NULL) {
//LOGE(".... **** ....CALLBACK NOT FOUND");
goto FAIL1;
}
}

jWidth = width;
jHeight = height;
LOGI("FrameReceived will reach here 1");

jRawImageBytes = (*env)->NewByteArray(env, size);
LOGI("FrameReceived will reach here 2");
(*env)->SetByteArrayRegion(env, jRawImageBytes, 0, size, rawImageBytes);
LOGI("FrameReceived will reach here 3");
//TODO will transform to NV21 in ndk (faster)
modifiedRawImageBytes = (*env)->NewByteArray(env, size);
LOGI("FrameReceived will reach here 4");
jint sizeWH = width * height;
jint quarter = sizeWH/4;
jint v0 = sizeWH + quarter;
LOGI("FrameReceived will reach here 5");
for (int u = sizeWH, v = v0, o = sizeWH; u < v0; u++, v++, o += 2) {
modifiedRawImageBytes[o] = jRawImageBytes[v]; // For NV21, V first
modifiedRawImageBytes[o + 1] = jRawImageBytes[u]; // For NV21, U second
}
LOGI("FrameReceived will reach here 6");
(*env)->SetByteArrayRegion(env, Array, 0, size, modifiedRawImageBytes);
LOGI("FrameReceived will reach here 7");

//LOGE(".... **** ....CALLBACK BEING CALLED");
if(remote)
{
(*env)->CallVoidMethod(env, applicationJniObj, frameReceivedRemoteMethod, 0, jWidth, jHeight, Array);
}
else
{
(*env)->CallVoidMethod(env, applicationJniObj, frameReceivedMethod, 0, jWidth, jHeight, Array);
}
//LOGE(".... **** ....CALLBACK CALLED");

(*env)->DeleteLocalRef(env, jRawImageBytes);

if (isAttached)
{
(*global_vm)->DetachCurrentThread(global_vm);
}
//LOGE("FrameReceived End");
return;
FAIL1:
if (isAttached)
{
(*global_vm)->DetachCurrentThread(global_vm);
}
FAIL0:
//LOGE("FrameReceived FAILED");
return;
}

И он всегда будет зависать после этого журнала: LOGI("FrameReceived will reach here 5"); в цикле FOR.
Что я здесь не так делаю?
Вот что я пытаюсь достичь в НДК:

открытый байт [] I420toNV21 (последний ввод байта [], вывод байта [], конечная ширина int, конечная высота int) {
if (output == null) {
выход = новый байт [input.length];
}
окончательный размер int = ширина * высота;
итоговая четверть = размер / 4;
final int v0 = размер + четверть;

    System.arraycopy(input, 0, output, 0, size); // Y is same

for (int u = size, v = v0, o = size; u < v0; u++, v++, o += 2) {
output[o] = input[v]; // For NV21, V first
output[o + 1] = input[u]; // For NV21, U second
}
return output;
}

Так что я могу отправить байтовый массив формата corect в Java. и не нужно делать этот метод в моем коде Java. Почему он не может добавить значение в цикле for в байтовый массив?

0

Решение

Поэтому, чтобы сделать это, я немного изменил логику.
Наличие char * rawImageBytes и его размер. Вместо прямого создания jbyteArray. Я выделю место для другого массива символов. и я скопирую память из первого, во второй.
Затем я вызываю цикл Loop, чтобы изменить то, что мне нужно, и только после этого я создаю jbyteArray:

char *modifiedRawImageBytes = malloc(size);
memcpy(modifiedRawImageBytes, rawImageBytes, size);
jint sizeWH = width * height;
jint quarter = sizeWH/4;
jint v0 = sizeWH + quarter;
for (int u = sizeWH, v = v0, o = sizeWH; u < v0; u++, v++, o += 2) {
modifiedRawImageBytes[o] = rawImageBytes[v]; // For NV21, V first
modifiedRawImageBytes[o + 1] = rawImageBytes[u]; // For NV21, U second
}
jWidth = width;
jHeight = height;

jRawImageBytes = (*env)->NewByteArray(env, size);
(*env)->SetByteArrayRegion(env, jRawImageBytes, 0, size, modifiedRawImageBytes);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]