Renderscript错误:未将内存对象设置到此分配中

huangapple go评论115阅读模式
英文:

Renderscript Error: no memory object set to this allocation

问题

我正在为 Android 的 camera2 编写一个 YUV 到 RGBA 的转换器,它通过 GPU 纹理获取输入,并返回一个 byte[](以及图像大小)。

在我测试的所有设备上都能正常工作,但在三星 Galaxy S9+ 上,首次运行脚本时我也会收到以下错误消息:

  1. E/RenderScript(14384): 错误:此分配没有设置内存对象:0x72072c2c80
  2. D/RenderScript(14384): [RS-DIAG] 不支持在 GPU 上使用已使用的分配
  3. D/RenderScript(14384): [RS-DIAG] 正在启动 CPU 脚本:slot(1) 46 0x71cad8a000

然后在以后的运行中:

  1. D/RenderScript(14384): [RS-DIAG] 由于先前的错误而禁用 GPU
  2. D/RenderScript(14384): [RS-DIAG] 正在启动 CPU 脚本:slot(1) 47 0x71cad8a000

我找不到关于上述两个错误消息的任何信息。我注意到尽管仍然会报告错误,但脚本似乎仍按预期工作,因为生成了正确的输出。

我对脚本在 GPU 上无法运行感到满意,但事实上,renderscript 报告了错误而不仅仅是警告,这让我感到困惑。

我猜我真正的问题是:是否可以安全地忽略此错误,或者在其他设备/更新的版本上会失败?

仅供参考,以下是我的代码:

  1. import android.graphics.ImageFormat;
  2. import android.renderscript.Allocation;
  3. import android.renderscript.Element;
  4. import android.renderscript.RenderScript;
  5. import android.renderscript.Type;
  6. import android.util.Log;
  7. import android.util.Size;
  8. import android.view.Surface;
  9. public class YUV420Converter implements Allocation.OnBufferAvailableListener {
  10. private static String TAG = "YUV420Converter";
  11. private Allocation mYUVInputAllocation;
  12. private Allocation mOutputAllocation;
  13. private Allocation mDummyInputAllocation;
  14. private Size mPreviewSize;
  15. private ScriptC_yuv2rgb mScriptC;
  16. private BGRA8888Listener mBGRA8888Listener;
  17. public interface BGRA8888Listener {
  18. public void newByteArray(byte[] bytes, Size size);
  19. }
  20. YUV420Converter(RenderScript rs, Size dimensions, BGRA8888Listener mBGRA8888Listener) {
  21. mPreviewSize = dimensions;
  22. this.mBGRA8888Listener = mBGRA8888Listener;
  23. createAllocation(rs, dimensions);
  24. mScriptC = new ScriptC_yuv2rgb(rs);
  25. mScriptC.set_gCurrentFrame(mYUVInputAllocation);
  26. mYUVInputAllocation.setOnBufferAvailableListener(this);
  27. }
  28. private void createAllocation(RenderScript rs, Size dimensions) {
  29. Type.Builder yuvTypeBuilder = new Type.Builder(rs, Element.YUV(rs));
  30. yuvTypeBuilder.setX(dimensions.getWidth());
  31. yuvTypeBuilder.setY(dimensions.getHeight());
  32. yuvTypeBuilder.setYuvFormat(ImageFormat.YUV_420_888);
  33. mYUVInputAllocation = Allocation.createTyped(rs, yuvTypeBuilder.create(),
  34. Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);
  35. Type.Builder rgbTypeBuilder = new Type.Builder(rs, Element.RGBA_8888(rs));
  36. rgbTypeBuilder.setX(dimensions.getWidth());
  37. rgbTypeBuilder.setY(dimensions.getHeight());
  38. mDummyInputAllocation = Allocation.createTyped(rs, rgbTypeBuilder.create(),
  39. Allocation.USAGE_SCRIPT);
  40. mOutputAllocation = Allocation.createTyped(rs, rgbTypeBuilder.create(),
  41. Allocation.USAGE_SCRIPT);
  42. }
  43. public Surface getInputNormalSurface() {
  44. return mYUVInputAllocation.getSurface();
  45. }
  46. @Override
  47. public void onBufferAvailable(Allocation a) {
  48. Log.d(TAG, "开始转换");
  49. long start = System.currentTimeMillis();
  50. // 获取最新的输入
  51. mYUVInputAllocation.ioReceive();
  52. // 运行处理过程
  53. mScriptC.forEach_yuv2rgb(mDummyInputAllocation, mOutputAllocation);
  54. byte[] b = new byte[mPreviewSize.getWidth() * mPreviewSize.getHeight() * 4];
  55. mOutputAllocation.copyTo(b);
  56. Log.d(TAG, "转换耗时:" + (System.currentTimeMillis() - start) + " 毫秒");
  57. mBGRA8888Listener.newByteArray(b, mPreviewSize);
  58. }
  59. }

此代码的使用类似于以下伪代码:

  1. renderScript = RenderScript.create(activity);
  2. yuvConverter = new YUV420Converter(renderScript, yuvCaptureSize, bgra8888Listener);
  3. List<Surface> surfaces = new ArrayList<>();
  4. surfaces.add(yuvConverter.getInputNormalSurface());
  5. cameraDevice.createCaptureSession(surfaces, ... );
  6. captureRequestBuilder.addTarget(yuvConverter.getInputNormalSurface());
  7. cameraCaptureSession.capture(captureRequestBuilder.build(), ...);

(以上内容仅为翻译结果,不包含问题回答部分)

英文:

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:

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

and then on later runs:

  1. D/RenderScript(14384): [RS-DIAG] GPU disabled due to earlier error
  2. 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:

  1. import android.graphics.ImageFormat;
  2. import android.renderscript.Allocation;
  3. import android.renderscript.Element;
  4. import android.renderscript.RenderScript;
  5. import android.renderscript.Type;
  6. import android.util.Log;
  7. import android.util.Size;
  8. import android.view.Surface;
  9. public class YUV420Converter implements Allocation.OnBufferAvailableListener {
  10. private static String TAG = &quot;YUV420Converter&quot;;
  11. private Allocation mYUVInputAllocation;
  12. private Allocation mOutputAllocation;
  13. private Allocation mDummyInputAllocation;
  14. private Size mPreviewSize;
  15. private ScriptC_yuv2rgb mScriptC;
  16. private BGRA8888Listener mBGRA8888Listener;
  17. public interface BGRA8888Listener {
  18. public void newByteArray(byte[] bytes, Size size);
  19. }
  20. YUV420Converter(RenderScript rs, Size dimensions, BGRA8888Listener mBGRA8888Listener) {
  21. mPreviewSize = dimensions;
  22. this.mBGRA8888Listener = mBGRA8888Listener;
  23. createAllocation(rs, dimensions);
  24. mScriptC = new ScriptC_yuv2rgb(rs);
  25. mScriptC.set_gCurrentFrame(mYUVInputAllocation);
  26. mYUVInputAllocation.setOnBufferAvailableListener(this);
  27. }
  28. private void createAllocation(RenderScript rs, Size dimensions) {
  29. Type.Builder yuvTypeBuilder = new Type.Builder(rs, Element.YUV(rs));
  30. yuvTypeBuilder.setX(dimensions.getWidth());
  31. yuvTypeBuilder.setY(dimensions.getHeight());
  32. yuvTypeBuilder.setYuvFormat(ImageFormat.YUV_420_888);
  33. mYUVInputAllocation = Allocation.createTyped(rs, yuvTypeBuilder.create(),
  34. Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);
  35. Type.Builder rgbTypeBuilder = new Type.Builder(rs, Element.RGBA_8888(rs));
  36. rgbTypeBuilder.setX(dimensions.getWidth());
  37. rgbTypeBuilder.setY(dimensions.getHeight());
  38. mDummyInputAllocation = Allocation.createTyped(rs, rgbTypeBuilder.create(),
  39. Allocation.USAGE_SCRIPT);
  40. mOutputAllocation = Allocation.createTyped(rs, rgbTypeBuilder.create(),
  41. Allocation.USAGE_SCRIPT);
  42. }
  43. public Surface getInputNormalSurface() {
  44. return mYUVInputAllocation.getSurface();
  45. }
  46. @Override
  47. public void onBufferAvailable(Allocation a) {
  48. Log.d(TAG, &quot;Beginning conversion&quot;);
  49. long start = System.currentTimeMillis();
  50. // Get to newest input
  51. mYUVInputAllocation.ioReceive();
  52. // Run processing pass
  53. mScriptC.forEach_yuv2rgb(mDummyInputAllocation, mOutputAllocation);
  54. byte[] b = new byte[mPreviewSize.getWidth() * mPreviewSize.getHeight() * 4];
  55. mOutputAllocation.copyTo(b);
  56. Log.d(TAG, &quot;Conversion took &quot; + (System.currentTimeMillis() - start) + &quot; ms&quot;);
  57. mBGRA8888Listener.newByteArray(b, mPreviewSize);
  58. }
  59. }

Which is used like in this pseudocode:

  1. renderScript = RenderScript.create(activity);
  2. yuvConverter = new YUV420Converter(renderScript, yuvCaptureSize, bgra8888Listener);
  3. List&lt;Surface&gt; surfaces = new ArrayList&lt;&gt;();
  4. surfaces.add(yuvConverter.getInputNormalSurface());
  5. cameraDevice.createCaptureSession(surfaces, ... );
  6. captureRequestBuilder.addTarget(yuvConverter.getInputNormalSurface());
  7. cameraCaptureSession.capture(captureRequestBuilder.build(), ...);

答案1

得分: 1

不清楚实际错误,但你可以尝试使用 Android 内置的 intrinisc 进行处理(是的,输出是 RGBA):
https://developer.android.com/reference/android/renderscript/ScriptIntrinsicYuvToRGB

英文:

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

huangapple
  • 本文由 发表于 2020年9月2日 19:29:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/63704587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定