尝试从Android摄像头获取最大fps
我正在开发一个Android应用程序,我需要从相机获得最大的fps 我一直在尝试使用缓冲区实现setPreviewCallbackWithBuffer,但无法使其工作 谁能给我举个例子或解释一下 我设置了一个计时器,每10毫秒运行一次,然后运行takePicture()。这是正确的,还是获得最大fps的方法 我已经到处找了,但找不到适合我的解释 多谢各位 编辑2:尝试从Android摄像头获取最大fps,android,camera,buffer,frame-rate,Android,Camera,Buffer,Frame Rate,我正在开发一个Android应用程序,我需要从相机获得最大的fps 我一直在尝试使用缓冲区实现setPreviewCallbackWithBuffer,但无法使其工作 谁能给我举个例子或解释一下 我设置了一个计时器,每10毫秒运行一次,然后运行takePicture()。这是正确的,还是获得最大fps的方法 我已经到处找了,但找不到适合我的解释 多谢各位 编辑2: startRecording.setOnClickListener( new View.OnClickListener() { pu
startRecording.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
if(!recording)
{
recording = true;
thread.start();
cam.startPreview();
Size previewSize=cam.getParameters().getPreviewSize();
int dataBufferSize=(int)(previewSize.height*previewSize.width*(ImageFormat.getBitsPerPixel(cam.getParameters().getPreviewFormat())/8.0));
cam.addCallbackBuffer(new byte[dataBufferSize]);
cam.addCallbackBuffer(new byte[dataBufferSize]);
cam.addCallbackBuffer(new byte[dataBufferSize]);
cam.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] imageData, Camera arg1) {
try {
photos.add(imageData);
} catch(Exception e) { System.out.println("ERROR!");
}
}
});
}
(...)
谢谢大家! 问题1:计时器
引述:
除了在屏幕上显示缓冲区外,还使用addCallbackBuffer(字节[])提供的缓冲区为每个预览帧安装要调用的回调。只要预览处于活动状态且缓冲区可用,就会重复调用回调。将覆盖任何其他预览回调
因此,删除您的计时器。调用setPreviewCallbackWithBuffer()
一次,将使用预览帧调用您,因为它们已准备好进行处理
问题2:硬编码缓冲区大小
引述:
对于YV12以外的格式,缓冲区的大小是通过将预览图像的宽度、高度和每像素字节数相乘来确定的。可以从getPreviewSize()读取宽度和高度。可以使用getPreviewFormat()中的图像格式,从getBitsPerPixel(int)/8计算每个像素的字节数
如果使用YV12格式,则可以使用setPreviewFormat(int)中列出的公式计算尺寸
请遵循这些说明,而不是猜测缓冲区大小
问题3:添加缓冲区
进一步引述:
将预先分配的缓冲区添加到预览回调缓冲区队列。应用程序可以向队列添加一个或多个缓冲区。当预览帧到达且至少有一个可用缓冲区时,将使用该缓冲区并将其从队列中移除。然后使用缓冲区调用预览回调。如果一帧到达并且没有剩余的缓冲区,则丢弃该帧。应用程序应该在处理完缓冲区中的数据后再添加缓冲区
调用setPreviewCallbackWithBuffer()
时,先调用addCallbackBuffer()
以获取一些缓冲区。在onPreviewFrame()
中,安排一个后台线程来处理该帧的缓冲区。完成该工作后,通过调用addCallbackBuffer()
将相同的缓冲区添加回池中。不要继续分配新的缓冲区。请完整准确地解释“我无法让它工作”的含义。“是这样吗”--不。@commonware我只是在主题中添加了代码和一些注释。你现在明白了吗?非常感谢。我编辑了主题,并按照您所说的内容将代码更改为现在的代码。我的问题是如何获得更多捕获?实际上我只拍了3张照片。另一个问题是为什么我保存的照片显示为全黑?您说过“完成该工作后,通过调用addCallbackBuffer()将相同的缓冲区添加回池中”。我该怎么做?我不明白。非常感谢@用户2989493:您似乎错过了问题3的大部分建议photos.add()
看起来不像是在后台线程上工作。当后台线程工作完成时,我看不到您正在通过addCallbackBuffer()
将已处理的缓冲区添加回池的位置。我正在将字节[]添加到ArrayList中,然后“线程”执行该工作(将字节[]保存到位图)。这是错误的做法吗?关于addCallbackBuffer(),我不明白我是如何做到的。你能解释一下吗?谢谢@user2989493:“这是一个错误的方法吗?”——因为我没有看到代码,所以我无法回答这个问题。但是,这听起来不太好,因为多个线程不能在同一个ArrayList
(使用其他工具,如LinkedBlockingQueue
)。“关于addCallbackBuffer(),我不明白我是怎么做到的”--你声称有一个线程。该线程正在运行一些代码来处理字节[]
。完成该代码后,您要做的最后一件事是调用addCallbackBuffer()
将byte[]
添加回缓冲池。现在我可以获得大约25 fps。问题是保存的照片是黑色图像。你有什么提示吗,或者你需要我发布代码?非常感谢!!;)