android camera2 将 TotalCaptureResult 与 Frame 相关联

android camera2 associate TotalCaptureResult with Frame

这是关于 Android 的 Camera2 API。由于捕获结果和输出帧是异步产生的,因此可以在实际帧之前获得捕获结果。有没有什么好的方法可以将生成的帧与相应的捕获结果相关联?

假设您正在谈论在捕获时发送到 ImageReaderSurfaceTexture 的帧(如无处不在的 camera2basic 示例),诀窍是比较唯一的时间戳识别图像。

  1. CameraCaptureSession.CaptureCallbackonCaptureComplete(...) 调用可用时,将 TotalCaptureResult 保存在可访问的地方。

  2. 然后,当通过您的 ImageReader.OnAvailableListenerSurfaceTexture.OnFrameAvailableListener 获得实际图像时,获取图像的时间戳:

Long imageTimestamp = Long.valueOf(reader.acquireNextImage().getTimestamp());

Long imageTimestamp = Long.valueOf(surfaceTexture.getTimestamp()),分别.

  1. 比较时间戳:imageTimestamp.equals(totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP));

备注:

  • 时间戳可能不是您设备的真实系统时间戳,但它保证是唯一的且单调递增,因此它可以用作 ID。

  • 如果您将图像发送到 SurfaceHolder 或其他东西,那么您就不走运了,因为只发送了像素信息,而不是 [= 中存在的时间戳21=] 对象。我不确定其他可以发送帧的地方,例如 MediaRecorderAllocation,但我认为不能。

  • 您可能需要在生成每个新的 TotalCaptureResult 时将它们添加到不断增长的集合中,然后将传入图像的时间戳与所有这些进行比较,因为您注意到的异步性质.我会让你想出你认为合适的方法。

我不得不解决类似的情况(跨表面同步帧); Sumner 的解决方案(.getTimestamp() 各自接收到的 Image 对象)为我解决了 SurfaceTextureImageReader.

只是对其他表面的快速说明(正如所指出的,不会给你一个 Image 对象):至少对于 MediaCodecBufferInfo object received by the onOutputBufferAvailable callback 有一个presentationTimeUs,即 "derived from the presentation timestamp passed in with the corresponding input buffer",至少对我来说, 看起来 以匹配来自其他表面的时间戳。 (不过请注意不同的单位。)