I am trying to write an app with android renderscript, failed to write edge detection part of a function. Observed that It works perfect if the device android version is less than or equal to Lolipop but in other devices, it most of the time (varies from build to build without depending on code changes as I observed) gives SIGSEV 11 or SIGBUS 7 errors with address faults.
This is edge detection rs implementation:
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};
}
or this does not work too:
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};
}
last two lines (return and uchar part) gives error. by the way if I wirte "return 10" or something like that, it works.
This is java part:
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);
}
there are multiple scriptC instances in the app. is this a problem or can it be ? (the exact same sobel edge detection codes working in other rs files without any problem)
Error:
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
Device: general mobile android one (android N)
Thanks for any help
You use unsigned data type to pass x and y values, and then expect things like
max(y - 1, (uint32_t)0);
to work correctly? You are making out of bound memory accesses left and right, hence errors.