【发布时间】:2017-01-16 13:30:11
【问题描述】:
我有一个代码可以访问来自前置摄像头的帧流并将它们推送到后台线程的处理。现在我根本没有使用任何缓冲区,一切正常(在我的手机上)。
那么对于这个特定任务,setPreviewCallback() 与 setPreviewCallbackWithBuffer() 有何不同?
【问题讨论】:
我有一个代码可以访问来自前置摄像头的帧流并将它们推送到后台线程的处理。现在我根本没有使用任何缓冲区,一切正常(在我的手机上)。
那么对于这个特定任务,setPreviewCallback() 与 setPreviewCallbackWithBuffer() 有何不同?
【问题讨论】:
后台处理的差异可能很大。相机缓冲区可能很大,setPreviewCallback() 会为每一帧单独分配(希望每秒 30 个)。这可能会对 JVM 造成很大的压力,因为缓冲区不会立即释放(并且 GC 不能依赖年轻代优化)。
setPreviewCallbackWithBuffer() 重用预分配的缓冲区,并且涉及到 GC。这也提供了一种简单的机制来为您的后台处理器获取足够的帧。例如,如果您只预先分配了 2 个帧缓冲区,那么在您有两帧发送处理后,将不会捕获第三帧(也减少了复制像素的 CPU 使用率),直到您调用 addCallbackBuffer() 释放一个缓冲区。
小心不要落入extra locks的陷阱:如果你提前释放缓冲区,你会承受Binder复制你实际丢弃的像素的开销。
【讨论】: