Reputation: 9557
I am working on a YUV->RGBA converter for android's camera2 that gets its input via GPU texture and returns a byte[]
(and the image size).
This works fine on all devices that I tested but on Samsung Galaxy S9+ I also get the following error messages on the first run of the script:
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
and then on later runs:
D/RenderScript(14384): [RS-DIAG] GPU disabled due to earlier error
D/RenderScript(14384): [RS-DIAG] Launching CPU script : slot(1) 47 0x71cad8a000
I could not find anything about the two error messages on top. I noticed that the script still seems to work as expected since the correct output is generated.
I am fine with the script not running on the GPU but the fact that renderscript reports an error and not just a warning throws me off.
I guess my real question is: Is this error safe to ignore or will it fail on other devices/newer versions?
Just for reference, here is my code:
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, rgbTypeBuilder.create(),
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);
}
}
Which is used like in this pseudocode:
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(), ...);
Upvotes: 1
Views: 168
Reputation: 311
No idea about the actual error, but you could try using the android intrinisc for that (yes, the output is RGBA): https://developer.android.com/reference/android/renderscript/ScriptIntrinsicYuvToRGB
Upvotes: 1