Android Renderscript 地址错误
Android Renderscript Address Fault
我正在尝试使用 android renderscript 编写应用程序,但无法编写功能的边缘检测部分。观察到,如果设备 android 版本小于或等于 Lolipop,但在其他设备中,它在大多数情况下(根据我观察到的代码更改而不同,因构建而异)给出 SIGSEV 11 或SIGBUS 7 错误,地址错误。
这是边缘检测 rs 实现:
uchar4 __attribute__((kernel)) Edge2( uchar in,uint32_t x, uint32_t y) {
//sobel
uint32_t n = max(y - 1, (uint32_t)0);
uint32_t s = min(y + 1, (uint32_t)height);
uint32_t e = min(x + 1, (uint32_t)width);
uint32_t w = max(x - 1, (uint32_t)0);
const uchar *e11 = rsGetElementAt(gIn, w, n);
const uchar *e21 = rsGetElementAt(gIn, x, n);
const uchar *e31 = rsGetElementAt(gIn, e, n);
const uchar *e12 = rsGetElementAt(gIn, w, y);
const uchar *e22 = rsGetElementAt(gIn, x, y);
const uchar *e32 = rsGetElementAt(gIn, e, y);
const uchar *e13 = rsGetElementAt(gIn, w, s);
const uchar *e23 = rsGetElementAt(gIn, x, s);
const uchar *e33 = rsGetElementAt(gIn, e, s);
float r1 = ((*e12 - *e32)*3 + *e11 + *e13 - *e31 - *e33);
float r2 = ((*e21 - *e23)*3 + *e11 - *e13 + *e31 - *e33);
uchar res=(uchar)clamp(sqrt((r1*r1+r2*r2)), 0.0f, 255.0f);
return (uchar4){res, res, res,(uchar)255};
}
或者这也行不通:
void Edge(const uchar *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y){
uint32_t n = max(y - 1, (uint32_t)0);
uint32_t s = min(y + 1, (uint32_t)height);
uint32_t e = min(x + 1, (uint32_t)width);
uint32_t w = max(x - 1, (uint32_t)0);
const uchar *e11 = rsGetElementAt(gIn, w, n);
const uchar *e21 = rsGetElementAt(gIn, x, n);
const uchar *e31 = rsGetElementAt(gIn, e, n);
const uchar *e12 = rsGetElementAt(gIn, w, y);
const uchar *e22 = rsGetElementAt(gIn, x, y);
const uchar *e32 = rsGetElementAt(gIn, e, y);
const uchar *e13 = rsGetElementAt(gIn, w, s);
const uchar *e23 = rsGetElementAt(gIn, x, s);
const uchar *e33 = rsGetElementAt(gIn, e, s);
// 1 0 -1
// 2 0 -2
// 1 0 -1
float r1 = ((*e12 - *e32)*3 + *e11 + *e13 - *e31 - *e33);
float r2 = ((*e21 - *e23)*3 + *e11 - *e13 + *e31 - *e33);
uchar res=(uchar)clamp(sqrt((r1*r1+r2*r2)), 0.0f, 255.0f);
*v_out = (uchar4){res, res, res,(uchar)255};
}
最后两行(return 和 uchar 部分)给出错误。顺便说一句,如果我写 "return 10" 或类似的东西,它就可以工作。
这是 java 部分:
public Bitmap doFilter(byte[] data) {
_inData.copy1DRangeFrom(0, _previewSamples, data);
_inData_yuv.copyFrom(data);
_filtersLib.forEach_Edge2(_inData, _outData);
yuvToRgbIntrinsic.forEach(_outData_rgb);
_filtersLib.forEach_combine(_outData, _outData);
_outData.copyTo(_outBmp);
return _outBmp;//Bitmap.createScaledBitmap(_outBmp, x, y, false);
}
应用中有多个 scriptC 实例。这是一个问题还是可以? (完全相同的 sobel 边缘检测代码在其他 rs 文件中工作没有任何问题)
错误:
Fatal signal 7 (SIGBUS), code 2, fault addr 0x8cf7ffff in tid 22666 (om.sketchcamera)
[ 12-27 18:36:37.275 317: 317 W/ ]
debuggerd: handling request: pid=22625 uid=10124 gid=10124 tid=22666
设备:普通手机android一台(androidN)
感谢您的帮助
您使用无符号数据类型传递 x 和 y 值,然后期望 max(y - 1, (uint32_t)0);
之类的东西能够正常工作?您正在左右进行超出限制的内存访问,因此会出错。
我正在尝试使用 android renderscript 编写应用程序,但无法编写功能的边缘检测部分。观察到,如果设备 android 版本小于或等于 Lolipop,但在其他设备中,它在大多数情况下(根据我观察到的代码更改而不同,因构建而异)给出 SIGSEV 11 或SIGBUS 7 错误,地址错误。
这是边缘检测 rs 实现:
uchar4 __attribute__((kernel)) Edge2( uchar in,uint32_t x, uint32_t y) {
//sobel
uint32_t n = max(y - 1, (uint32_t)0);
uint32_t s = min(y + 1, (uint32_t)height);
uint32_t e = min(x + 1, (uint32_t)width);
uint32_t w = max(x - 1, (uint32_t)0);
const uchar *e11 = rsGetElementAt(gIn, w, n);
const uchar *e21 = rsGetElementAt(gIn, x, n);
const uchar *e31 = rsGetElementAt(gIn, e, n);
const uchar *e12 = rsGetElementAt(gIn, w, y);
const uchar *e22 = rsGetElementAt(gIn, x, y);
const uchar *e32 = rsGetElementAt(gIn, e, y);
const uchar *e13 = rsGetElementAt(gIn, w, s);
const uchar *e23 = rsGetElementAt(gIn, x, s);
const uchar *e33 = rsGetElementAt(gIn, e, s);
float r1 = ((*e12 - *e32)*3 + *e11 + *e13 - *e31 - *e33);
float r2 = ((*e21 - *e23)*3 + *e11 - *e13 + *e31 - *e33);
uchar res=(uchar)clamp(sqrt((r1*r1+r2*r2)), 0.0f, 255.0f);
return (uchar4){res, res, res,(uchar)255};
}
或者这也行不通:
void Edge(const uchar *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y){
uint32_t n = max(y - 1, (uint32_t)0);
uint32_t s = min(y + 1, (uint32_t)height);
uint32_t e = min(x + 1, (uint32_t)width);
uint32_t w = max(x - 1, (uint32_t)0);
const uchar *e11 = rsGetElementAt(gIn, w, n);
const uchar *e21 = rsGetElementAt(gIn, x, n);
const uchar *e31 = rsGetElementAt(gIn, e, n);
const uchar *e12 = rsGetElementAt(gIn, w, y);
const uchar *e22 = rsGetElementAt(gIn, x, y);
const uchar *e32 = rsGetElementAt(gIn, e, y);
const uchar *e13 = rsGetElementAt(gIn, w, s);
const uchar *e23 = rsGetElementAt(gIn, x, s);
const uchar *e33 = rsGetElementAt(gIn, e, s);
// 1 0 -1
// 2 0 -2
// 1 0 -1
float r1 = ((*e12 - *e32)*3 + *e11 + *e13 - *e31 - *e33);
float r2 = ((*e21 - *e23)*3 + *e11 - *e13 + *e31 - *e33);
uchar res=(uchar)clamp(sqrt((r1*r1+r2*r2)), 0.0f, 255.0f);
*v_out = (uchar4){res, res, res,(uchar)255};
}
最后两行(return 和 uchar 部分)给出错误。顺便说一句,如果我写 "return 10" 或类似的东西,它就可以工作。
这是 java 部分:
public Bitmap doFilter(byte[] data) {
_inData.copy1DRangeFrom(0, _previewSamples, data);
_inData_yuv.copyFrom(data);
_filtersLib.forEach_Edge2(_inData, _outData);
yuvToRgbIntrinsic.forEach(_outData_rgb);
_filtersLib.forEach_combine(_outData, _outData);
_outData.copyTo(_outBmp);
return _outBmp;//Bitmap.createScaledBitmap(_outBmp, x, y, false);
}
应用中有多个 scriptC 实例。这是一个问题还是可以? (完全相同的 sobel 边缘检测代码在其他 rs 文件中工作没有任何问题)
错误:
Fatal signal 7 (SIGBUS), code 2, fault addr 0x8cf7ffff in tid 22666 (om.sketchcamera)
[ 12-27 18:36:37.275 317: 317 W/ ]
debuggerd: handling request: pid=22625 uid=10124 gid=10124 tid=22666
设备:普通手机android一台(androidN)
感谢您的帮助
您使用无符号数据类型传递 x 和 y 值,然后期望 max(y - 1, (uint32_t)0);
之类的东西能够正常工作?您正在左右进行超出限制的内存访问,因此会出错。