使用分配和RenderScript内存错误 [英] Memory errors using Allocations and RenderScript

查看:2087
本文介绍了使用分配和RenderScript内存错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作现场直播了WiFi相机到我的Andr​​oid平板电脑。我有图像采集卡运行在一个线程,这反过来又需要的像素,并将它们传递到renderScript做一些滤波处理(另一个线程)。我的输出分配被链接到水面进行查看。

该应用程序将与SIGSEGV故障周期性崩溃,显示器说,这是发生在任何一个线程,GCDaemon或JNISurfaceTexture。我有2个内核,我目前正在运行(可切换),都将最终失败。更基本的内核是仅有的像素[]从照相机到输入分配,在那里它被发送到renderScript然后'的forEach'调用的结果输出分配使用.ioSend发送到表面()。

如果我从相机线程像素[]数组,并直接将其复制到输出的分配,并调用.ioSend(),它永远不会崩溃(即规避RenderScript调用)。我还可以创建另一个输出分配(临时之一),并以此作为的forEach调用的返回输出的分配,这个复制到面联动输出分配,它不会崩溃,但我得到了一些奇怪的像素化的影响视频。

我还是有点新到renderScript但莫不是我不知道一些线程安全问题?或者在RS一个bug()?

下面是我如何配置我的输入和输出分配:

  android.renderscript.Element elemIN = android.renderscript.Element.createPixel(MRS,android.renderscript.Element.DataType.UNSIGNED_8,android.renderscript.Element.DataKind.PIXEL_RGBA);
        Type.Builder TypeIn =新Type.Builder(MRS,elemIN);        mAllocationIn = Allocation.createTyped(MRS,
            TypeIn.setX(videoWidth).setY(videoHeight).create(),
            Allocation.MipmapControl.MIPMAP_NONE,
            Allocation.USAGE_SCRIPT);

  mAllocationOut = Allocation.createTyped(MRS,TypeOUT.setX(videoWidth).setY(videoHeight).create()
            Allocation.MipmapControl.MIPMAP_NONE,
            (Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT));

下面是我简单的RGB内核:

  uchar4 __attribute __((内核))toRgb_Color(uchar4中){
    float4变量ndviPixel;
    uchar4出来;    ndviPixel.r =(浮点)(在[0] / 255.0);
    ndviPixel.g =(浮点)([1] / 255.0);
    ndviPixel.b =(浮子)(以[2] / 255.0);
    ndviPixel.a = 1.0F;    OUT = rsPackColorTo8888(ndviPixel);
    ndviPixel = 0;    返回的;
}

最后,我的内核调用是:

  mScript.forEach_toRgb_Color(mAllocationIn,mAllocationTemp);

更新

下面是如何,我宣布我的TypeOUT:

  mAllocationOut = Allocation.createTyped(MRS,TypeOUT.setX(videoWidth).setY(videoHeight).create()
            Allocation.MipmapControl.MIPMAP_NONE,
            (Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT));

另外,我在等待表面从onSurfaceTextureAvailable事件创建像这样:

 公共无效onSurfaceTextureAvailable(表面纹理表面纹理,诠释的宽度,高度INT){
      mSurface =新的表面(表面纹理);
}

在创建我的输入和输出的分配,我用的是锁'mSurface设置输出分配的输出表面,像这样的:

  mAllocationOut.setSurface(mSurface);

我mSurface声明为静态的,如果有什么差别。我试着带和不带静电,我仍然得到崩溃。

监视器输出是在这里:

  12月4日至23日:59:54.752:A / libc的(15192):致命信号11(SIGSEGV),code 1,在15230 TID故障地址为0x0(线程1697)
12月4日至23日:59:54.853:I / DEBUG(189):*** *** *** *** *** *** *** *** *** *** *** * ** *** *** *** ***
12月4日至23日:59:54.853:I / DEBUG(189):建立指纹:NVIDIA / wx_na_wf / shieldtablet:5.0.1 / LRX22C / 29979_515.3274:用户/释放键
12月4日至23日:59:54.853:I / DEBUG(189):修订:0
12月4日至23日:59:54.853:I / DEBUG(189):ABI:ARM
12月4日至23日:59:54.854:I / DEBUG(189):PID:15192,TID:15230,名称:螺纹1697>>> helios.android<<<
12月4日至23日:59:54.854:I / DEBUG(189):11(SIGSEGV),code 1(SEGV_MAPERR),故障地址为0x0
12月4日至23日:59:54.876:I / DEBUG(189):R0,R1 6f81a568 R2 00000001 00000000 00000000 R3
12月4日至23日:59:54.877:I / DEBUG(189):R4 630a3200 R5 6f81a568 R6 00000000 00000001 R7
12月4日至23日:59:54.877:I / DEBUG(189):R8 12c24000 R9 7c9a0f40 SL 7e86d404 FP 00000008
12月4日至23日:59:54.877:I / DEBUG(189):IP 7f8e1a10 SP 7f8e1970 LR 4211475d PC 420d3f72 CPSR 200f0030
12月4日至23日:59:54.878:I / DEBUG(189):回溯:
12月4日至23日:59:54.878:I / DEBUG(189):#00件000d3f72 /system/lib/libart.so(无效std::__1::__tree_remove<std::__1::__tree_node_base<void*>*>(std::__1::__tree_node_base<void*>*,的std :: __ 1 :: __ tree_node_base&LT;无效*&GT; *)+ 205)
12月4日至23日:59:54.878:I / DEBUG(189):#01件00114759 /system/lib/libart.so(艺术:: GC ::分配器:: RosAlloc :: RefillRun(艺术::主题*,无符号INT)+232)
12月4日至23日:59:54.878:I / DEBUG(189):#02件00114973 /system/lib/libart.so(艺术:: GC ::分配器:: RosAlloc :: AllocFromRun(艺术::主题*,无符号整型,无符号整型*)+ 490)
12月4日至23日:59:54.879:I / DEBUG(189):#03件0028ba97 /system/lib/libart.so(artAllocObjectFrom codeInitializedRosAlloc + 98)
12月4日至23日:59:54.879:I / DEBUG(189):#04件000a23cb /system/lib/libart.so(art_quick_alloc_object_initialized_rosalloc + 10)
12月4日至23日:59:54.879:I / DEBUG(189):#05件001d6359 /data/dalvik-cache/arm/system@framework@boot.oat
12月4日至23日:59:55.360:I / DEBUG(189):墓碑写到:/数据/墓碑/ tombstone_01
12月4日至23日:59:55.361:I / BootReceiver(659):复制/数据/墓碑/ tombstone_01到DropBox的(SYSTEM_TOMBSTONE)


解决方案

的问题是你要访问的输入分配的方式。在分配的每个元素具备所有的4个组成部分。但是,它不能作为在这里完成视为阵列。试试这个:

  uchar4 __attribute __((内核))toRgb_Color(uchar4中){
    float4变量tmpPixel = convert_float4(中);    //这个副本最有可能是不必要的,但对于做
    //完整性。
    float4变量ndviPixel.r = tmpPixel.x;
           ndviPixel.g = tmpPixel.y;
           ndviPixel.b = tmpPixel.z;
           ndviPixel.a = 255.0;
    uchar4 OUT = rsPackColorTo8888(ndviPixel);
    返回的;
}

I am working on live streaming a WiFi camera to my Android tablet. I have the frame grabber running in a Thread, which in turn takes the pixels and passes them to RenderScript to do some filter processing (another Thread). My output Allocation is linked to a Surface for viewing.

The app will crash periodically with SIGSEGV faults, the monitor says it's happening in either a Thread, GCDaemon or JNISurfaceTexture. I have 2 kernels I am currently running (switchable) and both will fail eventually. The more basic kernel is just a pixel [] from the camera into the input Allocation, where it is sent to RenderScript and then the result output Allocation of the 'forEach' call is sent to the surface using .ioSend().

If I take the pixel [] array from the camera thread and copy it directly to the output Allocation, and call .ioSend(), it never crashes (i.e. circumventing RenderScript calls). I can also create another output allocation (temp one) and use this as the return output allocation of the 'forEach' call, copy this to the Surface linked output Allocation and it will not crash, although I do get some strange pixelation effects in the video.

I'm still a bit new to RenderScript but could there be some thread safety issues I am not aware of? Or perhaps a bug in RS()?

Here is how I am configuring the input and output Allocations:

 android.renderscript.Element elemIN = android.renderscript.Element.createPixel(mRS, android.renderscript.Element.DataType.UNSIGNED_8, android.renderscript.Element.DataKind.PIXEL_RGBA);
        Type.Builder TypeIn = new Type.Builder( mRS, elemIN );

        mAllocationIn = Allocation.createTyped( mRS,
            TypeIn.setX( videoWidth ).setY( videoHeight ).create(),   
            Allocation.MipmapControl.MIPMAP_NONE,    
            Allocation.USAGE_SCRIPT );

and

  mAllocationOut = Allocation.createTyped( mRS, TypeOUT.setX( videoWidth ).setY( videoHeight ).create(),   
            Allocation.MipmapControl.MIPMAP_NONE,    
            ( Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT ) );  

Here is my simple RGB kernel:

 uchar4 __attribute__((kernel)) toRgb_Color( uchar4 in ) {
    float4 ndviPixel;
    uchar4 out;

    ndviPixel.r = ( float )( in[0] / 255.0 );
    ndviPixel.g = ( float )( in[1] / 255.0 );
    ndviPixel.b = ( float )( in[2] / 255.0 );
    ndviPixel.a = 1.0f;

    out = rsPackColorTo8888(ndviPixel);
    ndviPixel = 0;

    return out;
}

Lastly, my call to the kernel is:

mScript.forEach_toRgb_Color( mAllocationIn, mAllocationTemp );

UPDATE

Here's how I'm declaring my TypeOUT:

  mAllocationOut = Allocation.createTyped( mRS, TypeOUT.setX( videoWidth ).setY( videoHeight ).create(),   
            Allocation.MipmapControl.MIPMAP_NONE,    
            ( Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT ) ); 

Also, I am waiting for the surface to be created from the onSurfaceTextureAvailable event like so:

  public void onSurfaceTextureAvailable( SurfaceTexture surfaceTexture, int width, int height ) {
      mSurface = new Surface( surfaceTexture );
}

After I create my input and output allocations, I use the latched 'mSurface' to set the output surface of the output allocation, like this:

        mAllocationOut.setSurface( mSurface );

I have mSurface declared as static if that makes any difference. I've tried to with and without static and I still get the crash.

Monitor output is here:

04-23 12:59:54.752: A/libc(15192): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 15230 (Thread-1697)
04-23 12:59:54.853: I/DEBUG(189): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
04-23 12:59:54.853: I/DEBUG(189): Build fingerprint: 'nvidia/wx_na_wf/shieldtablet:5.0.1/LRX22C/29979_515.3274:user/release-keys'
04-23 12:59:54.853: I/DEBUG(189): Revision: '0'
04-23 12:59:54.853: I/DEBUG(189): ABI: 'arm'
04-23 12:59:54.854: I/DEBUG(189): pid: 15192, tid: 15230, name: Thread-1697  >>> helios.android <<<
04-23 12:59:54.854: I/DEBUG(189): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
04-23 12:59:54.876: I/DEBUG(189):     r0 6f81a568  r1 00000001  r2 00000000  r3 00000000
04-23 12:59:54.877: I/DEBUG(189):     r4 630a3200  r5 6f81a568  r6 00000000  r7 00000001
04-23 12:59:54.877: I/DEBUG(189):     r8 12c24000  r9 7c9a0f40  sl 7e86d404  fp 00000008
04-23 12:59:54.877: I/DEBUG(189):     ip 7f8e1a10  sp 7f8e1970  lr 4211475d  pc 420d3f72  cpsr 200f0030
04-23 12:59:54.878: I/DEBUG(189): backtrace:
04-23 12:59:54.878: I/DEBUG(189):     #00 pc 000d3f72  /system/lib/libart.so (void std::__1::__tree_remove<std::__1::__tree_node_base<void*>*>(std::__1::__tree_node_base<void*>*, std::__1::__tree_node_base<void*>*)+205)
04-23 12:59:54.878: I/DEBUG(189):     #01 pc 00114759  /system/lib/libart.so (art::gc::allocator::RosAlloc::RefillRun(art::Thread*, unsigned int)+232)
04-23 12:59:54.878: I/DEBUG(189):     #02 pc 00114973  /system/lib/libart.so (art::gc::allocator::RosAlloc::AllocFromRun(art::Thread*, unsigned int, unsigned int*)+490)
04-23 12:59:54.879: I/DEBUG(189):     #03 pc 0028ba97  /system/lib/libart.so (artAllocObjectFromCodeInitializedRosAlloc+98)
04-23 12:59:54.879: I/DEBUG(189):     #04 pc 000a23cb  /system/lib/libart.so (art_quick_alloc_object_initialized_rosalloc+10)
04-23 12:59:54.879: I/DEBUG(189):     #05 pc 001d6359  /data/dalvik-cache/arm/system@framework@boot.oat
04-23 12:59:55.360: I/DEBUG(189): Tombstone written to: /data/tombstones/tombstone_01
04-23 12:59:55.361: I/BootReceiver(659): Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)

解决方案

The issue is the way you are accessing the input Allocation. Each element in the Allocation is provided with all 4 components. But, it cannot be treated as an array as done here. Try this instead:

uchar4 __attribute__((kernel)) toRgb_Color( uchar4 in ) {
    float4 tmpPixel = convert_float4(in);

    //  This copy is most likely unnecessary, but done for
    //  completeness.
    float4 ndviPixel.r = tmpPixel.x;
           ndviPixel.g = tmpPixel.y;
           ndviPixel.b = tmpPixel.z;
           ndviPixel.a = 255.0;
    uchar4 out = rsPackColorTo8888(ndviPixel);
    return out;
}

这篇关于使用分配和RenderScript内存错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆