我在视频播放时遇到丢帧问题。我们刚从ICS转到KK4.4。视频的分辨率非常小,为320x240。没有音频可以让事情变得简单。
Systrace位于以下位置:https://www.dropbox.com/s/bee6xymg3kpn4ft/mytrace2.html?dl=0
我已经启用了Triple Buffering,hwcomposer正在生成SurfaceFlinger的伪vsync。
我可以看到以下问题:
-
由于视频解码器分配了7个缓冲区队列,因此未正确启用三重缓冲区。如果三重缓冲对于从TimedEventQueue(OnVideoEvent(排队的每个帧都能正常工作,那么应该出列的缓冲区应该落后2个插槽。例如:如果我们对buf4进行排队,那么buf2应该被取消排队,但被取消排队的是前一个缓冲区,surfaceflinger只有在下次有机会运行时才会释放。因此,延迟反过来又会导致视频的取消缓冲区赶上。
-
SurfaceFlinger本身需要一些时间才能完成。
-
Vsync没有在适当的时间打开,比如说对于30fps的视频,每33ms打开一次。HWComposer中的vsync生成逻辑存在问题,或者由于没有实际的缓冲区排队而导致eventControl未启用vsync?
根据我的以下评论进行更新:我注意到的其他事情是,async和mDequeueBufferCannotBlock标志都是false,因此getMinUndqueuedBufferCount((返回1,因此我们看到前一个缓冲区被要求出列,而不是后面2个插槽的缓冲区。请让我知道以上理解是否有漏洞。以及我能做的任何事情来绕过这个
非常感谢您的帮助。
-
视频编解码器决定它们需要多少缓冲区。BufferQueue配置是一个协商。
-
我看不出SurfaceFlinger花了很长时间才完成。看看
/system/bin/surfaceflinger
行,它运行得很快。 -
在没有工作可做的时候醒来做工作是没有价值的,所以如果什么都没发生,VSYNC就会被关闭。后一种假设是正确的——如果您查看
SurfaceView
行,您可以在SurfaceFlinger中看到没有可用缓冲区和没有唤醒之间的相关性。
我看到SurfaceView
BufferQueue上的帧到达之间有180ms,大约是5.5fps。在媒体服务器过程中有一些长的onVideoEvent
部分——你使用的是什么编解码器?
你把这描述为一个"丢帧"的问题——你在用哪个播放器?