首页 > 解决方案 > 可以使用 Camera2 API 指定任意目标 fps 范围吗?

问题描述

在我们的移动应用程序中,Android 设备上的摄像头捕获作为视频流发送到远程服务器。

我需要自动调整我的相机 fps 以适应网络速度。基本上,如果我检测到网络很慢,我需要降低 fps 并继续降低它,直到达到平衡。

CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES我使用Camera2 API 上的字段获取可用的 fps 范围。CONTROL_AE_TARGET_FPS_RANGE我使用字段设置目标 fps 。

假设可能的范围列表是 (30, 30) 和 (15, 30)。

我首先将目标设置为最高 fps(在我们的例子中为 (30, 30))。一旦我检测到网络很慢,我将 fps 范围减小到 (15, 30)。但是,我注意到该设备继续产生约 29 fps 的速度。

作为一个实验,我强制目标 fps 值为 (15, 15)。这似乎成功了。系统开始生成 15 fps,这是我所期望的值。

但是,这让我想知道CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES和之间的关系到底是什么CONTROL_AE_TARGET_FPS_RANGE。我的印象是,在相机上设置的目标范围必须是从接收到的值之一 CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES。在我的情况下,这将是 (30, 30) 或 (15, 30)。但是,如果 (15, 15) 也被接受为有效的目标 fps,我想知道是否可以在有效范围内指定任何范围。例如,我想将 fps 设置为 (29, 29)、(28, 28) 等,直到达到平衡。这是允许的吗?

标签: androidandroid-camera2

解决方案


一般来说,答案是否定的。

合同要求所有支持的 FPS 范围都以CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES. 此外,当您选择不支持的相机参数(例如帧速率或预览大小)时,设备的行为是不确定的。一些设备会抛出 RuntimeException,另一个可能会保留当前设置,而另一个会选择“尽可能接近您的要求”

一些设备不会发布所有支持的 FPS 范围,而且 API 并不总是可以完全实现。例如,考虑一个可以以 30 FPS 提供全高清 1920x1080 帧的相机,但对于较小的 1280x720 帧支持 60 FPS?它应该发布哪些受支持的 FPS 范围?如果这些设置取决于其他一些选择,例如夜景模式或焦距怎么办?

而且我还没有谈到在不太完善的设备上经常发生的错误。经常看到设备声明支持某些支持的 FPS 或支持大小,但实际上无法设置它(同样,有各种结果)。

如果您的应用程序或库打算使用各种硬件覆盖数百万用户,您别无选择,只能为可能使用和可能不使用的设备功能保留某些白名单和黑名单,并考虑制造商,设备型号,有时甚至是系统版本(例如,我看到无线升级破坏了某些,公认的边缘,相机功能)。

另一个注意事项是浮动 FPS 范围不能用于视频录制或传输。如果你选择 (15, 30) 范围,你会遇到很多视频播放器的问题,音频永远不会与视频同步,你仍然无法控制比特率。


TL;NR:在您的具体情况下,无需担心不受支持的无证 (15、15) FPS 范围。您可以轻松地每秒丢弃一帧,并将 15 FPS 传递到网络,同时仍保持支持的 (30, 30) 范围。如果您需要任意统一的速率,例如 20 FPS,那么您就不太幸运了。有一些方法可以稍微延迟下一帧的传递,但没有人会保证这些帧之间会经过 50000000 纳秒。


推荐阅读