android camera2 将 TotalCaptureResult 与 Frame 相关联
android camera2 associate TotalCaptureResult with Frame
这是关于 Android 的 Camera2 API。由于捕获结果和输出帧是异步产生的,因此可以在实际帧之前获得捕获结果。有没有什么好的方法可以将生成的帧与相应的捕获结果相关联?
假设您正在谈论在捕获时发送到 ImageReader
或 SurfaceTexture
的帧(如无处不在的 camera2basic 示例),诀窍是比较唯一的时间戳识别图像。
当 CameraCaptureSession.CaptureCallback
的 onCaptureComplete(...)
调用可用时,将 TotalCaptureResult
保存在可访问的地方。
然后,当通过您的 ImageReader.OnAvailableListener
或 SurfaceTexture.OnFrameAvailableListener
获得实际图像时,获取图像的时间戳:
Long imageTimestamp = Long.valueOf(reader.acquireNextImage().getTimestamp());
或
Long imageTimestamp = Long.valueOf(surfaceTexture.getTimestamp())
,分别.
- 比较时间戳:
imageTimestamp.equals(totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP));
备注:
时间戳可能不是您设备的真实系统时间戳,但它保证是唯一的且单调递增,因此它可以用作 ID。
如果您将图像发送到 SurfaceHolder
或其他东西,那么您就不走运了,因为只发送了像素信息,而不是 [= 中存在的时间戳21=] 对象。我不确定其他可以发送帧的地方,例如 MediaRecorder
或 Allocation
,但我认为不能。
您可能需要在生成每个新的 TotalCaptureResult
时将它们添加到不断增长的集合中,然后将传入图像的时间戳与所有这些进行比较,因为您注意到的异步性质.我会让你想出你认为合适的方法。
我不得不解决类似的情况(跨表面同步帧); Sumner 的解决方案(.getTimestamp()
各自接收到的 Image 对象)为我解决了 SurfaceTexture
和 ImageReader
.
只是对其他表面的快速说明(正如所指出的,不会给你一个 Image
对象):至少对于 MediaCodec
,BufferInfo
object received by the onOutputBufferAvailable
callback 有一个presentationTimeUs
,即 "derived from the presentation timestamp passed in with the corresponding input buffer",至少对我来说, 看起来 以匹配来自其他表面的时间戳。 (不过请注意不同的单位。)
这是关于 Android 的 Camera2 API。由于捕获结果和输出帧是异步产生的,因此可以在实际帧之前获得捕获结果。有没有什么好的方法可以将生成的帧与相应的捕获结果相关联?
假设您正在谈论在捕获时发送到 ImageReader
或 SurfaceTexture
的帧(如无处不在的 camera2basic 示例),诀窍是比较唯一的时间戳识别图像。
当
CameraCaptureSession.CaptureCallback
的onCaptureComplete(...)
调用可用时,将TotalCaptureResult
保存在可访问的地方。然后,当通过您的
ImageReader.OnAvailableListener
或SurfaceTexture.OnFrameAvailableListener
获得实际图像时,获取图像的时间戳:
Long imageTimestamp = Long.valueOf(reader.acquireNextImage().getTimestamp());
或
Long imageTimestamp = Long.valueOf(surfaceTexture.getTimestamp())
,分别.
- 比较时间戳:
imageTimestamp.equals(totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP));
备注:
时间戳可能不是您设备的真实系统时间戳,但它保证是唯一的且单调递增,因此它可以用作 ID。
如果您将图像发送到
SurfaceHolder
或其他东西,那么您就不走运了,因为只发送了像素信息,而不是 [= 中存在的时间戳21=] 对象。我不确定其他可以发送帧的地方,例如MediaRecorder
或Allocation
,但我认为不能。您可能需要在生成每个新的
TotalCaptureResult
时将它们添加到不断增长的集合中,然后将传入图像的时间戳与所有这些进行比较,因为您注意到的异步性质.我会让你想出你认为合适的方法。
我不得不解决类似的情况(跨表面同步帧); Sumner 的解决方案(.getTimestamp()
各自接收到的 Image 对象)为我解决了 SurfaceTexture
和 ImageReader
.
只是对其他表面的快速说明(正如所指出的,不会给你一个 Image
对象):至少对于 MediaCodec
,BufferInfo
object received by the onOutputBufferAvailable
callback 有一个presentationTimeUs
,即 "derived from the presentation timestamp passed in with the corresponding input buffer",至少对我来说, 看起来 以匹配来自其他表面的时间戳。 (不过请注意不同的单位。)