以 30 FPS 存储 android 预览帧的最佳方式是什么?
What is the best way to store android preview frames at 30 FPS?
我们正在开发一个利用 Android 预览功能的项目。我们正在以最大可用分辨率(目前为 1600 x 1200)捕获预览。
要求将预览的每一帧都保存在辅助存储器上。 OnPreviewFrame
能够以 30 FPS(约 30 milliseconds/frame)进行预览,但是当添加代码以保存数据时,它会限制 FPS。
目前已测试:
OnPreviewFrame
和在主线程中保存 JPEG。在这种情况下,保存大约需要 250-260 毫秒。因此,FPS 变为 5-6.
OnPreviewFrame
在主线程中,在另一个线程中保存 JPEG。因此,为保存的每一帧创建一个新线程。如果线程在内存中(质量因数 60 时每个线程大约需要 450-500 毫秒)并且当内存被释放时,在预览中观察到一个间隙,它会创建很多。
那么,是否有任何可能的解决方法可以让我们以 30 FPS 的速度保存所有帧?
YuvImage yuvImage = new YuvImage(data, activity.previewFormat, activity.previewWidth, activity.previewHeight, null);
FileOutputStream fos = new FileOutputStream(this.file);
yuvImage.compressToJpeg(new Rect(0, 0, activity.previewWidth, activity.previewHeight), 60, fos);
fos.flush();
fos.close();
您正在进行大量消耗资源的操作。有些像磁盘I/O一样无法避免,其他的可以显着减少。
- 内存分配和取消分配 (GC) 非常昂贵
任务。考虑预分配 15-30 帧并使用帧池。
- 线程创建非常昂贵。考虑使用一个后台线程
它将轮询一些队列以获取帧并将 return 帧轮询到帧
保存后的池。 (如果单线程不能按时完成保存文件的任务,可以考虑提前分配线程池)。
- I/O 必须像您建议的那样在后台线程上完成。
我们正在开发一个利用 Android 预览功能的项目。我们正在以最大可用分辨率(目前为 1600 x 1200)捕获预览。
要求将预览的每一帧都保存在辅助存储器上。 OnPreviewFrame
能够以 30 FPS(约 30 milliseconds/frame)进行预览,但是当添加代码以保存数据时,它会限制 FPS。
目前已测试:
OnPreviewFrame
和在主线程中保存 JPEG。在这种情况下,保存大约需要 250-260 毫秒。因此,FPS 变为 5-6.OnPreviewFrame
在主线程中,在另一个线程中保存 JPEG。因此,为保存的每一帧创建一个新线程。如果线程在内存中(质量因数 60 时每个线程大约需要 450-500 毫秒)并且当内存被释放时,在预览中观察到一个间隙,它会创建很多。
那么,是否有任何可能的解决方法可以让我们以 30 FPS 的速度保存所有帧?
YuvImage yuvImage = new YuvImage(data, activity.previewFormat, activity.previewWidth, activity.previewHeight, null);
FileOutputStream fos = new FileOutputStream(this.file);
yuvImage.compressToJpeg(new Rect(0, 0, activity.previewWidth, activity.previewHeight), 60, fos);
fos.flush();
fos.close();
您正在进行大量消耗资源的操作。有些像磁盘I/O一样无法避免,其他的可以显着减少。
- 内存分配和取消分配 (GC) 非常昂贵 任务。考虑预分配 15-30 帧并使用帧池。
- 线程创建非常昂贵。考虑使用一个后台线程 它将轮询一些队列以获取帧并将 return 帧轮询到帧 保存后的池。 (如果单线程不能按时完成保存文件的任务,可以考虑提前分配线程池)。
- I/O 必须像您建议的那样在后台线程上完成。