【问题标题】:Inconsistent video quality when encoding camera preview frames with MediaCodec on Xperia Z1在 Xperia Z1 上使用 MediaCodec 编码相机预览帧时视频质量不一致
【发布时间】:2014-01-06 19:45:02
【问题描述】:

我正在编码来自相机预览的NV21 帧。由于某种原因,在其他设备上运行良好的架构在 Sony Xperia Z1Android 4.3 上运行不正确。它发回质量不正确(低)的编码帧。

MediaCodec 的格式是COLOR_FormatYUV420SemiPlanar,即NV12(我通过交换U 和V 分量将NV21 转换为NV12)。 MediaCodec 发回给我的输出缓冲区的大小非常小,与我正在使用的分辨率 (1280x720) 和比特率 (1000000) 不对应。前几帧的质量很好,但随后显着下降:

int encoderStatus = mMediaCodec.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
// a few encoderStatus checks skipped
ByteBuffer encodedData = outputBuffers[encoderStatus];
Log.i(Constants.TAG, "Buffer size " + mBufferInfo.size);

这让我在 Xperia Z1 上获得以下日志:

Buffer size 26
Buffer size 52172
Buffer size 23650
Buffer size 14394
Buffer size 3591
Buffer size 1849
Buffer size 3908

...

Buffer size 1043
Buffer size 248
Buffer size 836
Buffer size 518
Buffer size 1112

来自Sony Xperia ZR 的示例日志,它可以正常工作:

Buffer size 21
Buffer size 51048
Buffer size 21063
Buffer size 24228
Buffer size 28040
...
Buffer size 44959
Buffer size 44972
Buffer size 44957
Buffer size 45004
Buffer size 44999
Buffer size 44957

任何建议将不胜感激。

【问题讨论】:

  • Xperia Z1 编码器似乎有一些特殊行为,例如stackoverflow.com/questions/20475332 。不过,对于 1280x720,您可能需要超过 1Mbps 的速度——在 30fps 时,每帧 4KB,而 Xperia ZR 的输出是 10 倍。所以有可能 ZR 坏了,Z1 正在做你告诉它的事情。提高比特率会改善问题吗?
  • 谢谢,fadden,您的评论和 mstorsjo 的回答为我指明了正确的方向。

标签: android android-mediacodec


【解决方案1】:

您确定以正确的单位(微秒)传递时间戳 - 并且设置了合理的帧速率吗?

  • 某些编码器可能会忽略时间戳,并且仅根据帧速率设置每帧的固定比特率预算。

  • 其他人可能会尝试根据时间戳计算每帧允许使用多少位。

如果给出时间戳,例如相反,以毫秒为单位,这可能导致编码器将编码帧的大小减小到零。

【讨论】:

  • 这就是问题所在。非常感谢。我将 System.currentTimeMillis() 作为第四个参数传递给 mMediaCodec.queueInputBuffer() 而我应该传递的是 System.nanoTime() / 1000。
  • Related: System.nanoTime() 是你处理帧的时间,而不是生成帧的时间,根据任务调度器的变幻莫测,时基可能会“摆动”一点.您可以使用SurfaceTexture#getTimestamp() 获取帧生成时间。
  • 感谢@fadden 提供的信息 不幸的是,我没有使用SurfaceTexture。我正在通过Camera.setPreviewCallbackWithBuffer() 设置预览回调中的帧。
  • 啊,我应该从 U/V 交换的评论中知道这一点。如果您可以将您的应用程序限制为 API 18+,并且您不需要在 YUV 空间中编辑帧,您应该考虑切换到 Surface——它的效率要高得多。 Grafika 在我的 Nexus 7 (2012) 上愉快地编码 60fps 预览。 (github.com/google/grafika)
  • 60fps 听起来确实很疯狂。我重新检查了一下,它实际上以 30fps(1280x720)的速度通过。 Grafika 正在使用相机默认设置;尚未尝试查看实际最大值是多少。 FWIW,Grafika 包括 1280x720 glReadPixels 速度测试;在某些设备上每帧需要 6 毫秒,在其他设备上需要 14 毫秒,在另一些设备上需要 170 毫秒。最后一个肯定是在走某种缓慢的道路。所以YMMV。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多