Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在某些设备中出现Android/NDK信号错误_Android_Crash_Android Ndk - Fatal编程技术网

仅在某些设备中出现Android/NDK信号错误

仅在某些设备中出现Android/NDK信号错误,android,crash,android-ndk,Android,Crash,Android Ndk,在Android/NDK下,我使用下一个算法将RGB转换为YUV420sp。我开始收到一些用户的少量崩溃报告。因此,在他们向我发送日志后,在下一个算法中,所有的算法似乎都失败了,在第二个算法中,我给出了一个注释,即解码argb888\u yuv42sp,日志显示了一个SIGILL错误,我发现它有下一个定义: 非法指令(ANSI)通常表示可执行文件 文件已损坏或使用了指向函数指针的数据 预料之中 这些报告都来自SGSII的skyrocket和Rogers变体,以及三星Captivate Glide

在Android/NDK下,我使用下一个算法将RGB转换为YUV420sp。我开始收到一些用户的少量崩溃报告。因此,在他们向我发送日志后,在下一个算法中,所有的算法似乎都失败了,在第二个算法中,我给出了一个注释,即解码argb888\u yuv42sp,日志显示了一个SIGILL错误,我发现它有下一个定义:

非法指令(ANSI)通常表示可执行文件 文件已损坏或使用了指向函数指针的数据 预料之中

这些报告都来自SGSII的skyrocket和Rogers变体,以及三星Captivate Glide。而且并非所有这些设备都有,因为其他一些使用这些设备的用户也报告说根本没有问题

这些设备硬件是否有特定的功能?或者任何已知的错误?还是我的代码有问题

JNIEXPORT void JNICALL Java_com_test_NatLib_decodeBitmapToYuv420sp(JNIEnv *env, jobject javaThis, jobject bitmap, jbyteArray yuv)
{
    AndroidBitmapInfo bitmapInfo;
    int code;
    void *nativeRGBPixels;

    if ((code = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo)) < 0)
    {
        return;
    }

    if ((code = AndroidBitmap_lockPixels(env, bitmap, (void**)&nativeRGBPixels)) < 0)
    {
        return;
    }

    char *nativeYuvPixels = (char*)env->GetByteArrayElements(yuv, 0);

    decodeARGB888_YUV420sp(nativeRGBPixels, nativeYuvPixels, bitmapInfo.width, bitmapInfo.height);

    env->ReleaseByteArrayElements(yuv, (jbyte*)nativeYuvPixels , 0);
    AndroidBitmap_unlockPixels(env, bitmap);
}

static void decodeARGB888_YUV420sp(const int *argb, char *yuv, const int width, const int height)
{
    const int totalPixels = width * height;
    int indexPixel = 0;
    int indexY = 0;
    int indexUV = totalPixels;
    int R, G, B, Y, U, V;
    int x, y;

    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {

//--------------------------------------------------------------------
// AT THIS POINT IS WHERE THE LAST LOG WITH SIGILL WAS CAPTURED
//--------------------------------------------------------------------

            const int pixelValue = argb[indexPixel];

            R = pixelValue & 0xff;
            G = (pixelValue & 0xff00) >> 8;
            B = (pixelValue & 0xff0000) >> 16;

            // RGB to YUV algorithm for component Y
            Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;

            // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2 meaning for
            // every 4 Y pixels there are 1 V and 1 U. Note the sampling is every other pixel AND every other scanline
            yuv[indexY++] = (char)((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));

            if (y % 2 == 0 && indexPixel % 2 == 0)
            {
                // RGB to YUV algorithm for component U & V
                U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
                V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

                yuv[indexUV++] = (char)((V < 0) ? 0 : ((V > 255) ? 255 : V));
                yuv[indexUV++] = (char)((U < 0) ? 0 : ((U > 255) ? 255 : U));
            }

            indexPixel++;
        }
    }
}
JNIEXPORT void JNICALL Java_com_test_NatLib_decodeBitmapToYuv420sp(JNIEnv*env,jobject javaThis,jobject bitmap,jbyteArray yuv)
{
AndroidBitmapInfo bitmapInfo;
int代码;
void*nativeRGBPixels;
if((code=AndroidBitmap_getInfo(环境、位图和位图))<0)
{
返回;
}
if((代码=AndroidBitmap_lockPixels(环境、位图、(void**)和nativeRGBPixels))<0)
{
返回;
}
char*nativeYuvPixels=(char*)env->GetByteArrayElements(yuv,0);
解码argb888_YUV420sp(nativeRGBPixels、nativeyuvpix、bitmapInfo.width、bitmapInfo.height);
环境->发布依据数据元素(yuv,(jbyte*)本地yuv像素,0);
AndroidBitmap_解锁像素(环境、位图);
}
静态无效解码argb888_YUV420sp(常量int*argb,char*yuv,常量int宽度,常量int高度)
{
const int totalPixels=宽度*高度;
int indexPixel=0;
int indexY=0;
int indexUV=总像素;
int R,G,B,Y,U,V;
int x,y;
对于(y=0;y<高度;y++)
{
对于(x=0;x>8;
B=(像素值&0xff0000)>>16;
//分量Y的RGB-to-YUV算法
Y=((66*R+129*G+25*B+128)>>8)+16;
//NV21具有Y平面和VU交错平面,每一个都以2的因子进行采样,表示
//每4 Y像素有1 V和1 U。注意,采样是每隔一个像素和每隔一条扫描线
yuv[indexY++]=(char)((Y<0)?0:((Y>255)?255:Y));
如果(y%2==0&&indexPixel%2==0)
{
//组件U&V的RGB到YUV算法
U=(-38*R-74*G+112*B+128)>>8+128;
V=((112*R-94*G-18*B+128)>>8)+128;
yuv[indexUV++]=(char)((V<0)?0:((V>255)?255:V));
yuv[indexUV++]=(char)((U<0)?0:((U>255)?255:U));
}
indexPixel++;
}
}
}

因为它是关于
SIGILL
的,所以很可能您正在丢失
env
,它的值变成了垃圾,处理器在内存中执行的某些区域不是指令(
text
),而是
数据。这是因为跳转目标是在
env
实例上计算的


你可以通过阅读获得一些关于env用法的指针。

@Zhenya,我认为实际的解决方案应该有所不同。您的Android.mk中可能包含以下内容:

#ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
   LOCAL_ARM_NEON := true
#endif

这是错误的。armeabi-v7a不一定意味着霓虹灯(如Tegra2芯片组)。相反,对NEON优化代码的检查应该始终是运行时检查,您可以在NDK中找到关于如何执行此操作的文档。

是的,我开始认为这可能是问题所在,但如果是这样,那么我不知道如何停止垃圾回收器或停止干扰参数的人。关于第二个方法签名,很抱歉这是一个打字错误,谢谢你发现它,我已经更新了答案。这可能是因为很多事情,因为我建议你阅读我有一种感觉这些都是Tegra2设备。您好,您评论中关于Tegra2设备的解决方案解决了这个问题。谢谢我同意你关于霓虹灯检查的意见,但是正如你在我的代码中看到的,我在算法中根本没有使用任何霓虹灯,因此没有理由认为它因为霓虹灯而失败。