android - 可以使用 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) 等,直到达到平衡。这是允许的吗?
解决方案
一般来说,答案是否定的。
合同要求所有支持的 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 纳秒。
推荐阅读
- c# - .NET MVC 在时间输入时禁用本机验证消息
- javascript - 重复单击时单击事件中的jQuery scrollTop无法正常工作
- php - 如何从mysqli导出到excel中的用户定义标题
- java - 比较两个列表和相同的值存储在第三个列表问题中
- java - FirebaseAuth - 修改后的用户登录名/电子邮件的复制
- java - 评估一个静态私有变量(Java),不应该是非法的吗?
- file - 上传文件时托管网站自己的服务器如何选择我的计算机目录?
- python - 检查该项目是否存在于 OrderedDict 的字典中
- java - 如何使用 Java swing 备份 MySQL 数据库中的单个表?
- javascript - Vaadin-tooltip 有时不显示。怎么了?如何以编程方式显示它?