1

我有这个过热问题,运行几个小时后它会关闭我的手机。我想 24/7 全天候运行,请帮助我改进:

我使用 Camera2 接口,RAW 格式后跟渲染脚本将 YUV420888 转换为 rgba。我的渲染脚本如下:

#pragma version(1)
#pragma rs java_package_name(com.sensennetworks.sengaze)
#pragma rs_fp_relaxed

rs_allocation gCurrentFrame;
rs_allocation gByteFrame;
int32_t gFrameWidth;

uchar4 __attribute__((kernel)) yuv2RGBAByteArray(uchar4 prevPixel,uint32_t x,uint32_t y)
{

    // Read in pixel values from latest frame - YUV color space
    // The functions rsGetElementAtYuv_uchar_? require API 18
    uchar4 curPixel;
    curPixel.r = rsGetElementAtYuv_uchar_Y(gCurrentFrame, x, y);
    curPixel.g = rsGetElementAtYuv_uchar_U(gCurrentFrame, x, y);
    curPixel.b = rsGetElementAtYuv_uchar_V(gCurrentFrame, x, y);

    // uchar4 rsYuvToRGBA_uchar4(uchar y, uchar u, uchar v);
    // This function uses the NTSC formulae to convert YUV to RBG
    uchar4 out = rsYuvToRGBA_uchar4(curPixel.r, curPixel.g, curPixel.b);

    rsSetElementAt_uchar(gByteFrame, out.r, 4 * (y*gFrameWidth + x) + 0 );
    rsSetElementAt_uchar(gByteFrame, out.g, 4 * (y*gFrameWidth + x) + 1 );
    rsSetElementAt_uchar(gByteFrame, out.b, 4 * (y*gFrameWidth + x) + 2 );
    rsSetElementAt_uchar(gByteFrame, 255, 4 * (y*gFrameWidth + x) + 3 );

    return out;
}

这是我调用渲染脚本转换为 rgba 的地方:

@Override
        public void onBufferAvailable(Allocation a) {
            inputAllocation.ioReceive();

            // Run processing pass if we should send a frame
            final long current = System.currentTimeMillis();
            if ((current - lastProcessed) >= frameEveryMs) {
                yuv2rgbaScript.forEach_yuv2RGBAByteArray(scriptAllocation, outputAllocation);
                if (rgbaByteArrayCallback != null) {
                    outputAllocationByte.copyTo(outBufferByte);
                    rgbaByteArrayCallback.onRGBAArrayByte(outBufferByte);
                }
                lastProcessed = current;
            }
        }

这是使用 OpenCV 运行图像处理的回调:

@Override
    public void onRGBAArrayByte(byte[] rgbaByteArray) {

        try {
            /* Fill images. */
            rgbaMat.put(0, 0, rgbaByteArray);

            analytic.processFrame(rgbaMat);

            /* Send fps to UI for debug purpose. */
            calcFPS(true);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

整个过程以〜22fps的速度运行。我仔细检查过,没有内存泄漏。但是即使在屏幕关闭的情况下运行一段时间后,手机也会变得非常热,并自行关闭。请注意,如果我删除图像处理部分,问题仍然存在。这有什么问题?我可以打开手机相机应用程序并让它运行几个小时而不会出现问题。

  • 渲染脚本会导致热量吗?
  • 22fps会导致热量吗?也许我应该减少它?
  • Android后台服务会不会发热?

谢谢。

ps:我在完全支持Camera2接口的LG G4上测试了这个。

4

1 回答 1

2

从理论上讲,如果您的设备开始过热,它应该自我节流,并且永远不要关闭。当设备预热时,这只会降低您的帧速率。但不幸的是,有些设备在这方面并没有达到应有的水平。

基本上,任何降低 CPU / GPU 使用率的东西都会降低功耗和发热。基本提示:

  • 不要复制缓冲区。当您以约 30fps 的速度进行复制时,每个副本都非常昂贵。在这里,您从 Allocation 复制到 byte[],然后从该 byte[] 复制到 rgbaMat。这是从分配复制到 rgbaMat 的 2 倍。不幸的是,我不确定是否有直接的方法可以从分配复制到 rgbaMat,或者创建一个由与 rgbaMat 相同的内存支持的分配。
  • 您确定不能对 YUV 数据进行 OpenCV 处理吗?这将为您节省大量开销;如果不在硬件中完成,RGB->YUV 转换并不便宜。
  • 还有一个 RS 内在函数ScriptIntrinsicYuvToRgb,它可以为您提供比您的手写循环更好的性能。
于 2017-03-30T19:51:32.873 回答