Android使用camera2复制内置视频录制质量和帧率

Posted

技术标签:

【中文标题】Android使用camera2复制内置视频录制质量和帧率【英文标题】:Android copy built-in video recording quality and framerate using camera2 【发布时间】:2019-06-25 02:10:20 【问题描述】:

使用 camera2 API 获得的图像质量和帧速率与我使用相机应用手动将视频录制到文件时获得的不匹配。

我正在尝试在 android 上使用 OpenCV 进行实时图像处理。我使用内置相机应用程序手动录制了一段视频,一切正常:图像质量很好,帧速率稳定在 30 FPS。

我的最低 SDK 版本是 22,所以我正在使用 camera2 API 的重复请求。我已经设置了它,连同 ImageReader 和 YUV_420_888 格式。我已经尝试了PREVIEWRECORD 捕获请求模板,尝试在构建器中手动设置 18 个捕获请求参数(例如禁用自动白平衡,将色彩校正模式设置为快速),但 FPS 是仍然在8-9左右,图像质量也很差。另一部手机产生了相同的结果,尽管它的最大值。 FPS 为 16.67(而不是 30)。

罪魁祸首不是我的图像处理(这发生在另一个线程中,除了读取图像的缓冲区):当我对帧不做任何事情时(我什至没有显示图像),我检查了 FPS,还是 8 点到 9 点左右。

您可以在此处查看相关代码:

//constructor:
HandlerThread thread = new HandlerThread("MyApp:CameraCallbacks", Process.THREAD_PRIORITY_MORE_FAVORABLE);
thread.start();
captureCallbackHandler = new Handler(thread.getLooper());
//some UI event:
cameraManager.openCamera(cameraId, new CameraStateCallback()), null);
//CameraStateCallback#onOpened:
//size is 1280x720, same as the manually captured video's
imageReader = ImageReader.newInstance(size.getWidth(), size.getHeight(), ImageFormat.YUV_420_888, 1);
imageReader.setOnImageAvailableListener(new ImageAvailableListener(), captureCallbackHandler);
camera.createCaptureSession(Collections.singletonList(imageReader.getSurface()), new CaptureStateCallback(), captureCallbackHandler);
//CaptureStateCallback#onConfigured:
CaptureRequest.Builder builder = activeCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
builder.addTarget(imageReader.getSurface());
//setting the FPS range has no effect: this phone only has one option
session.setRepeatingRequest(builder.build(), null, captureCallbackHandler);
//ImageAvailableListener#onImageAvailable:
long current = System.nanoTime();
deltaTime += (current - last - deltaTime) * 0.1;
Log.d("MyApp", "onImageAvailable FPS: " + (1000000000 / deltaTime));
//prints around 8.7
last = current;
try (Image image = reader.acquireLatestImage())  

【问题讨论】:

它是旧设备吗? 我一次又一次地看到,camera2 API 为传统相机提供了次优结果。我强烈建议在这种情况下使用已弃用的 Camera API。 谢谢你的建议,我会试试的。完成后我会在这里分享结果。 不要忘记调用 Camera.open() from a background HadlerThread 以获得最佳性能! 可能无法击败内置录制应用程序或 MediaRecorder,因为它们可能会使用相机硬件与 avc 编解码器之间的快捷方式,从而在共享中传递像素内存,并且涉及零拷贝。对于 camera2 API (ImageFormat.PRIVATE),这种方法已“公开”,但这对 LEGACY 设备没有帮助。 【参考方案1】:

在三星 Galaxy J3 (2016) 上,执行Camera.Parameters#setRecordingHint(true)(同时使用已弃用的相机 API)完全达到了我想要的效果:视频质量和帧速率与内置录像机的相同。不幸的是,这也意味着我无法修改分辨率,并且在 Doogee X5 MAX 上设置该提示并没有达到同样的效果。

【讨论】:

以上是关于Android使用camera2复制内置视频录制质量和帧率的主要内容,如果未能解决你的问题,请参考以下文章

Android制作一个视频录制器

Android制作一个视频录制器

Android制作一个视频录制器

Android Camera2 API:捕获视频而不预览

android 采集摄像头预览帧,使用opencv和MediaCodec直接录制水印滤镜视频

android 采集摄像头预览帧,使用opencv和MediaCodec直接录制水印滤镜视频