0

我正在尝试存储和操作来自相机预览的数据流帧。执行此操作的代码非常简单(即使转换 YUV->RGB),但帧速率很糟糕。

如果我只打开预览并写出所有 YUV 数据(YUV 格式为 640x480 * 1.5),我的帧率低于 8FPS。如果我不做任何存储,帧率会上升到 100FPS(这意味着回调必须与硬件分离,但这没什么大不了的)。

在我继续解决这个问题之前,我只是在处理我的硬件限制吗?要求手机每秒存储30次461k是不是很不合理?我意识到它是 13 兆/秒,但我正在重用分配的空间。所以这不是内存问题,而是处理速度问题,老实说,我不知道这是否是一个不合理的要求。

有没有其他人试图操纵从 Android 相机流出的数据?

感谢您抽时间阅读。

4

2 回答 2

4

我的第一个问题是,您是否使用 Previewcallbacks 来处理来自 Preview 的字节?

如果是,提高帧率的一种方法是使用带有缓冲区的预览回调。请参阅http://developer.android.com/reference/android/hardware/Camera.html#setPreviewCallbackWithBuffer%28android.hardware.Camera.PreviewCallback%29以获取参考。

另一个不错的可能性是将您的处理放在一个单独的线程中。这是一个例子:

private ExecutorService processingExecutor;
// ...
this.processingExecutor = Executors.newSingleThreadExecutor();
public void onPreviewFrame(final byte[] data, final Camera camera) {

    processingExecutor.execute(new Runnable() {
        public void run() {
            processImage(data);
        }
    });
    // update your view here

    camera.addCallbackBuffer(data);
}

protected void processImage(byte[] data) {
    // do you processing here

}

不要忘记视图只能从 UI 线程更新。

于 2012-11-11T19:51:10.603 回答
1

从问题的描述来看,我很清楚这个问题纯粹是由于您的文件写入系统的数据率非常高。正如您正确指出的那样,存储 30VGA (640x480)张图像相当于13.2 MBytes/sec,大约是106 Mbits/sec。这是极高的数据速率,并且存储相同的数据需要非常高速的存储介质以及相关的软件更改。

如果您将未压缩的YUV帧存储到 SD 卡中,从 SD 卡的规格中,您会发现您需要一UHS类卡。请参阅此链接以获取更多详细信息:http ://en.wikipedia.org/wiki/Secure_Digital#Speed_Class_Rating

如果要存储到内部闪存中,则必须找出最大值。您的存储设备的数据传输速率,以了解您的理论限制。

总而言之,如果您希望存储 30 VGA 帧/秒,那么

  1. 正如 Alex Chap 已经指出的那样,文件写入必须在单独的线程中异步。

  2. 应该仔细选择此线程的优先级,以确保它不会与系统中的其他活动线程竞争。有时文件系统写入可能需要一些时间,如果您的线程由于文件系统更新而被阻塞,那么如果没有仔细选择优先级,您可能会导致系统阻塞。

  3. 必须仔细选择队列中的缓冲区数量。接收器,即YUV帧的文件写入将是链中较慢的部分。为了重用一组固定的缓冲区,您必须确定可以处理系统中抖动的缓冲区的数量,即即使文件写入速度很慢,您仍然可以继续继续捕获视频帧。这将对您的用例的内存需求产生巨大影响。

于 2013-03-14T23:44:45.253 回答