我应该从逆时针旋转每个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)上启动此方法时,它工作正常,但当我在Samsung S3(v4.3)和联想P-70(v4.4.2)上启动应用程序时,该应用程序崩溃了。在Android Studio的Android监视器选项卡中,我看到了 内存使用量一直在增加,直到我的应用程序崩溃。在我的htc中,我没有遇到任何问题。有什么想法吗?
答案 0 :(得分:2)
您使用GetByteArrayElements
和arr
对data
执行加倍yuv
,然后才释放yuv
。您也不会检查是否使用最后一个参数创建了副本,只需输入JNI_FALSE
即可。你不应该这样做,你应该使用布尔参数来接收值,而不是试图告诉系统是否要复制。
因此,您应该最后释放两个指针。
此外,如果此代码有效,则意味着副本实际上是由于您正在从同一内存区域进行读写而导致图像损坏。