我应该将我从相机接收到的每个 yuv 图像缓冲区逆时针旋转 90 度。我找到了这个 post在哪里使用java。此代码工作正常。 但我尝试过使用本地方法,因为我想使用具有相同逻辑但运行速度更快的方法。
JNIEXPORT jbyteArray JNICALL Java_com_ndk_example_utils_NativeUtils_rotateFrameBackward
(JNIEnv *env, jobject obj, jbyteArray arr, jint w, jint h){
jint arrSize = w*h*3/2;
jbyte *data,*yuv;
data = (*env)->GetByteArrayElements(env, arr, JNI_FALSE);
yuv = (*env)->GetByteArrayElements(env, arr, JNI_FALSE);
int x,y,i = 0;
for(x = 0; x < w; x++){
for(y = h-1;y >= 0;y--){
yuv[i] = data[y*w+x];
i++;
}
}
i = arrSize - 1;
for(x = w-1;x > 0;x=x-2)
{
for(y = 0;y < h/2;y++)
{
yuv[i] = data[(w*h)+(y*w)+x];
i--;
yuv[i] = data[(w*h)+(y*w)+(x-1)];
i--;
}
}
(*env)->ReleaseByteArrayElements(env, arr, yuv, JNI_ABORT);
yuv = 0;
data = 0;
return arr;
}
当我在我的 htc 816(v5.1) 上启动这个方法时它工作正常,但是当我在三星 S3(v4.3) 和联想 P-70(v4.4.2) 上启动这个应用程序时,应用程序崩溃了.在 Android Studio 的 Android 监视器选项卡中,我看到了 内存使用量一直在增加,直到我的应用程序崩溃。在我的 htc 中,我没有遇到任何问题。有什么想法吗?
最佳答案
您使用data
和yuv
为arr
执行双重GetByteArrayElements
,然后只释放yuv
。您也不检查是否使用最后一个参数制作了副本,您只需输入 JNI_FALSE
。你不应该那样做,你应该使用一个 bool 参数来接收值,而不是试图告诉系统是否复制。
因此,您应该在最后释放两个指针。
此外,如果此代码有效,则意味着实际上已创建副本,因为您正在从同一内存区域读取和写入,这会导致图像损坏。
关于Android NDK 内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35746149/