Renderscript错误:未为此分配设置任何内存对象

问题描述

我正在为Android的camera2开发YUV-> RGBA转换器,该转换器通过GPU纹理获取其输入并返回byte[](以及图像大小)。

这在我测试过的所有设备上都可以正常运行,但在Samsung Galaxy S9 +上,我在脚本的第一次运行时也会收到以下错误消息:

E/RenderScript(14384): Error: no memory object set to this allocation: 0x72072c2c80
D/RenderScript(14384): [RS-DIAG] A used allocation is not supported on the GPU
D/RenderScript(14384): [RS-DIAG] Launching CPU script : slot(1) 46 0x71cad8a000

,然后在以后运行:

D/RenderScript(14384): [RS-DIAG] GPU disabled due to earlier error
D/RenderScript(14384): [RS-DIAG] Launching CPU script : slot(1) 47 0x71cad8a000

我在顶部找不到有关两个错误消息的任何信息。我注意到,由于生成了正确的输出,该脚本似乎仍然可以按预期工作。

对于脚本不在GPU上运行的情况,我很好,但renderscript报告错误而不只是警告会使我失望。

我猜我真正的问题是:这个错误可以忽略吗,还是在其他设备/较新版本上失败?

仅供参考,这是我的代码:

import android.graphics.ImageFormat;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.Type;
import android.util.Log;
import android.util.Size;
import android.view.Surface;

public class YUV420Converter implements Allocation.OnBufferAvailableListener {
    private static String TAG = "YUV420Converter";
    private Allocation mYUVInputAllocation;
    private Allocation mOutputAllocation;
    private Allocation mDummyInputAllocation;
    private Size mPreviewSize;
    private ScriptC_yuv2rgb mScriptC;
    private BGRA8888Listener mBGRA8888Listener;

    public interface BGRA8888Listener {
        public void newByteArray(byte[] bytes,Size size);
    }

    YUV420Converter(RenderScript rs,Size dimensions,BGRA8888Listener mBGRA8888Listener) {
        mPreviewSize = dimensions;
        this.mBGRA8888Listener = mBGRA8888Listener;
        createAllocation(rs,dimensions);

        mScriptC = new ScriptC_yuv2rgb(rs);
        mScriptC.set_gCurrentFrame(mYUVInputAllocation);
        mYUVInputAllocation.setOnBufferAvailableListener(this);
    }

    private void createAllocation(RenderScript rs,Size dimensions) {
        Type.Builder yuvTypeBuilder = new Type.Builder(rs,Element.YUV(rs));
        yuvTypeBuilder.setX(dimensions.getWidth());
        yuvTypeBuilder.setY(dimensions.getHeight());
        yuvTypeBuilder.setYuvFormat(ImageFormat.YUV_420_888);
        mYUVInputAllocation = Allocation.createTyped(rs,yuvTypeBuilder.create(),Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);

        Type.Builder rgbTypeBuilder = new Type.Builder(rs,Element.RGBA_8888(rs));
        rgbTypeBuilder.setX(dimensions.getWidth());
        rgbTypeBuilder.setY(dimensions.getHeight());
        mDummyInputAllocation = Allocation.createTyped(rs,rgbTypeBuilder.create(),Allocation.USAGE_SCRIPT);
        mOutputAllocation = Allocation.createTyped(rs,Allocation.USAGE_SCRIPT);
    }

    public Surface getInputNormalSurface() {
        return mYUVInputAllocation.getSurface();
    }

    @Override
    public void onBufferAvailable(Allocation a) {
        Log.d(TAG,"Beginning conversion");
        long start = System.currentTimeMillis();
        // Get to newest input
        mYUVInputAllocation.ioReceive();

        // Run processing pass
        mScriptC.forEach_yuv2rgb(mDummyInputAllocation,mOutputAllocation);
        
        byte[] b = new byte[mPreviewSize.getWidth() * mPreviewSize.getHeight() * 4];
        mOutputAllocation.copyTo(b);
        Log.d(TAG,"Conversion took " + (System.currentTimeMillis() - start) + " ms");
        mBGRA8888Listener.newByteArray(b,mPreviewSize);
    }
}

在此伪代码中的用法如下:

renderScript = RenderScript.create(activity);
yuvConverter = new YUV420Converter(renderScript,yuvCaptureSize,bgra8888Listener);

List<Surface> surfaces = new ArrayList<>();
surfaces.add(yuvConverter.getInputNormalSurface());
cameraDevice.createCaptureSession(surfaces,... );

captureRequestBuilder.addTarget(yuvConverter.getInputNormalSurface());
cameraCaptureSession.capture(captureRequestBuilder.build(),...);

解决方法

不知道实际错误,但是您可以尝试使用android intrinisc来解决(是的,输出是RGBA): https://developer.android.com/reference/android/renderscript/ScriptIntrinsicYuvToRGB

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...