在某些设备上未调用Camera onPreviewFrame()(不显示预览显示)

时间:2019-02-02 19:26:25

标签: java android android-camera

在我的两个设备之一上,onPreviewFrame没有被调用,尽管我使用相同的代码。

我试图获取(使用OpenCV处理),然后使用不建议使用的相机API显示相机帧。 (因为我使用的是LEGACY设备,不推荐使用的API为此提供了更好的性能。)

这意味着我不想直接显示预览帧,但是我能够确定在此设备上设置显示器是拍摄预览所必需的。这意味着我必须设置某种高性能的虚拟显示器。我的选项是:setPreviewDisplay-> SurfaceHoldersetPreviewTexture-> SurfaceTexture

我了解到的另一件事是setPreviewCallbackWithBuffer在该设备上也不起作用:我必须使用setPreviewCallback

理想情况下,我想检测是否需要这些额外的步骤才能进行预览:如果没有必要,我不想在不需要它们的设备上进行这些操作。

我无法为SurfaceHolder方法找到伪setPreviewDisplay,因此无法使用该方法调用预览回调。在另一方面,setPreviewTexture一个新的SurfaceTexture确实让onPreviewFrame被调用,但我经常收到“BufferQueue已被放弃”的错误和预览数据似乎不正确,以及:我设置图像格式时,从所述数据创建的图像不正确。查看不同的颜色会使图像显示不同的颜色。同样,同一代码可在另一台设备上工作,并且我设置了图像格式,因此输出应该有效。

我当前的代码,其中调用onPreviewFrame,但数据无效:

camera = Camera.open();
camera.setPreviewTexture(new SurfaceTexture(1));
camera.setPreviewCallback(this);
camera.setParameters(configurator.getParameters()); //sets the resolution (same on both devices), the fps range and the format to ImageFormat.YV12 (or NV21, makes no difference)
camera.startPreview();

不需要预览显示的手机:Doogee X5 MAX
出现问题的手机:三星Galaxy J3(2016)

2 个答案:

答案 0 :(得分:1)

回复:虚拟预览纹理,这是您可以获得的最佳解决方法。官方API要求预览必须放在某个地方,并且大多数设备都必须执行此政策。

无法在运行时检查设备是否提供实时预览,而无需绘制“水槽”(表面或纹理)。在其他类似情况下,我们会根据质量检查实验室实验和最终用户的投诉,被迫维护设备的白名单和黑名单。对于某些功能,该技术是在应用程序的第一次运行(在特定设备上)尝试最佳设置,如果崩溃或失败,则在第二次尝试中使用效率较低的替代方法,并将此标志保留在 SharedPreferences (将来的发布)。

幸运的是,添加虚拟 SurfaceTexture 不会对性能产生负面影响,即使在没有该功能的设备上也是如此。

为避免出现“ BufferQueue被放弃” 错误,请add虚拟 SurfaceTexture 作为您的活动或片段中的字段。

答案 1 :(得分:1)

setPreviewCallbackWithBuffer无法正常工作,因为缓冲区太小。直到摆脱了“ BufferQueue has been抛弃”错误,我才看到错误。缓冲区太小的原因是:

  • 我没有查询预览大小,我只是使用了将预览大小设置为的值

  • 我打电话给Camera.Parameters#setRecordingHint(true),这将我的分辨率(可能还有其他设置)锁定为硬编码值。此分辨率与我选择的分辨率不同,因此我的缓冲区确实太小了。