【问题标题】:I'm trying to modify a byte array and send it from c++ to java via the JNI我正在尝试修改一个字节数组并通过 JNI 将其从 c++ 发送到 java
【发布时间】:2018-09-15 05:51:15
【问题描述】:

这是我的功能:

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;
}

它总是会在这个 LOG 之后崩溃:FOR 循环中的LOGI("FrameReceived will reach here 5");。 我在这里做错了什么? 这就是我想要在 NDK 中实现的目标:

public byte[] I420toNV21(final byte[] input, byte[] output, final int width, final int height) { 如果(输出==空){ 输出=新字节[输入.长度]; } 最终的 int 大小 = 宽度 * 高度; 最终 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循环中的值添加到字节数组中?

【问题讨论】:

    标签: android c++ arrays java-native-interface jbytearray


    【解决方案1】:

    所以为了做到这一点,我改变了一点逻辑。 拥有 char *rawImageBytes,它的大小。而不是直接创建一个 jbyteArray。我将为另一个 char 数组分配空间。我将从第一个复制内存,在第二个。 然后我调用for循环,为了修改我需要的,只有在那之后,我才会创建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);
    

    【讨论】:

      猜你喜欢
      • 2012-07-22
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 2010-10-26
      • 2019-05-02
      • 2011-09-08
      相关资源
      最近更新 更多