gpt4 book ai didi

android - 如何减少 MediaCodec 视频/avc 解码中的延迟

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:48:49 25 4
gpt4 key购买 nike

我对 MoviePlayer.java 进行了一些简单的计时在Grafika在 Nexus 5 上运行的 MediaCodec 示例代码。我在这些位置放置了一条日志语句:

在第 203 行之前

decoder.queueInputBuffer

在第 244 行之后

decoder.dequeueOutputBuffer

我使用 presentationTimeUs 关联了日志语句。

这是 logcat 的摘录:

01-29 10:56:43.295: I/Grafika(21286): queueInputBuffer index/pts, 2,0
01-29 10:56:43.305: I/Grafika(21286): queueInputBuffer index/pts, 0,33100
01-29 10:56:43.315: I/Grafika(21286): queueInputBuffer index/pts, 3,66466
01-29 10:56:43.325: I/Grafika(21286): queueInputBuffer index/pts, 1,99833
01-29 10:56:43.325: I/Grafika(21286): queueInputBuffer index/pts, 2,133200
01-29 10:56:43.335: I/Grafika(21286): queueInputBuffer index/pts, 0,166566
01-29 10:56:43.345: I/ATSParser(21286): discontinuity on stream pid 0x1011
01-29 10:56:43.345: I/ATSParser(21286): discontinuity on stream pid 0x1100
01-29 10:56:43.345: I/Grafika(21286): queueInputBuffer index/pts, 3,199933
01-29 10:56:43.345: I/Grafika(21286): dequeueOutputBuffer index/pts, 7,0
01-29 10:56:43.345: I/Grafika(21286): queueInputBuffer index/pts, 1,300033
01-29 10:56:43.355: I/Grafika(21286): dequeueOutputBuffer index/pts, 6,33100
01-29 10:56:43.385: I/Grafika(21286): queueInputBuffer index/pts, 2,333400
01-29 10:56:43.385: I/Grafika(21286): dequeueOutputBuffer index/pts, 5,66466
01-29 10:56:43.415: I/Grafika(21286): queueInputBuffer index/pts, 0,366766
01-29 10:56:43.415: I/Grafika(21286): dequeueOutputBuffer index/pts, 4,99833
01-29 10:56:43.445: I/Grafika(21286): queueInputBuffer index/pts, 3,400133
01-29 10:56:43.445: I/Grafika(21286): dequeueOutputBuffer index/pts, 3,133200

我发现从第一个输入缓冲区排队到相应的输出缓冲区出列的时间差为 50 毫秒。这似乎是硬件加速解码的很多时间。

有没有办法减少这种延迟?

最佳答案

我认为您看到了第一帧独有的一些效果。我重复了您的实验,并在第 244 行附近进一步添加了强制 doRender = false 以避免用于管理输出帧速率的 sleep 调用。我明白了:

01-29 14:05:36.552  9115  9224 I Grafika : queueInputBuffer index/pts, 2,0
01-29 14:05:36.562 9115 9224 I Grafika : queueInputBuffer index/pts, 0,66655
01-29 14:05:36.572 9115 9224 I Grafika : queueInputBuffer index/pts, 3,133288
01-29 14:05:36.582 9115 9224 I Grafika : queueInputBuffer index/pts, 1,199955

01-29 14:05:36.602 9115 9224 I Grafika : dequeueOutputBuffer index/pts, 4,0
01-29 14:05:36.602 9115 9224 I Grafika : dequeueOutputBuffer index/pts, 3,66655
01-29 14:05:36.602 9115 9224 I Grafika : dequeueOutputBuffer index/pts, 2,133288
01-29 14:05:36.612 9115 9224 I Grafika : dequeueOutputBuffer index/pts, 4,199955

(为清楚起见,删除了多余的行。)这证实了您的结果。请注意,虽然 pts=0 时输入和输出之间有 50 毫秒的滞后,但随后的输出帧几乎立即可用。我使用的视频是“camera-test.mp4”(720p 相机输出)。

要深入了解发生这种情况的原因,请查看日志中的其他内容及其出现的位置。从第一个 queueInputBuffer 日志行开始,计算该行与第一个 dequeueOutputBuffer 行之间出现的日志数。我数了一下我的 OMX-VDEC-1080P 大约有 60 行输出。现在计算在输出缓冲区开始出现后出现了多少 OMX-VDEC 线。在视频结束之前我什么都看不到。

视频解码器显然推迟了一些昂贵的初始化,直到数据可用。所以下一个问题是……它需要多少数据?我在提交第二帧后添加了 500ms sleep (pts==66633)。结果:两帧提交,500ms 暂停,两帧提交,一大堆 OMX-VDEC 日志。因此,解码器似乎需要几帧才能开始。

这表明我们可以通过快速输入前几帧来减少启动延迟。为了对此进行测试,我将 TIMEOUT_USEC 更改为零,因此它会快速响应但会消耗 CPU。新的日志输出(你的日志,没有 sleep ,没有渲染):

01-29 14:29:04.542 10560 10599 I Grafika : queueInputBuffer index/pts, 0,0
01-29 14:29:04.542 10560 10599 I Grafika : queueInputBuffer index/pts, 2,66633
01-29 14:29:04.542 10560 10599 I Grafika : queueInputBuffer index/pts, 3,133288
...
01-29 14:29:04.572 10560 10599 I Grafika : dequeueOutputBuffer index/pts, 4,0
01-29 14:29:04.572 10560 10599 I Grafika : dequeueOutputBuffer index/pts, 3,66633
01-29 14:29:04.572 10560 10599 I Grafika : dequeueOutputBuffer index/pts, 2,133288

通过快速输入初始帧,我们将初始延迟从 50 毫秒减少到 30 毫秒。

(请注意所有时间戳如何以“2”结尾?用于日志时间的计时器似乎四舍五入到最接近的 10 毫秒,因此实际时间增量可能略有不同。)

我们缓慢地提供初始帧的原因是我们试图在提交每个输入缓冲区后从解码器中排出输出,等待 10 毫秒以等待从未出现的输出。我最初的想法是,我们想要等待超时 either dequeueInputBuffer() or dequeueOutputBuffer(),但不是两者兼而有之——可能首先使用输入超时和快速轮询输出,然后当我们用完输入时切换到输出超时。 (就此而言,输入的初始超时可以是 -1,因为我们知道在第一个输入缓冲区排队之前什么都不会发生。)

我不知道是否有进一步减少延迟的方法。

关于android - 如何减少 MediaCodec 视频/avc 解码中的延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21440820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com