mpv播放视频缓慢问题
目录
现象
分析
基础软硬件对比
解码性能测试
mpv参数介绍
gpu-context参数
debug参数
现场debug日志
指定gpu-context参数
mpv统计信息
正常统计
异常统计
EDID信息及显示信息
总结
现象
在机器A上播放视频需要时间1分钟,在机器B上播放同一视频需要几分钟。
初期,用mpv播放rtsp流会出现慢的问题,经本地测试,同样慢。
测试视频1080P 60fps h265
现象被描述为卡顿,和实际有所区别。理清实际现象是第一步。
分析
基础软硬件对比
采用 显卡硬解码,对比两个机器的硬解码设备,都是正常。链路正常,也没有错误,完全一致。

软件对比
故障机器有占CPU高的进程,通过将这些进程停掉,再进行测试问题依旧。
解码性能测试
采用前述文章中的不带窗口显示的shell命令,对视频解码性能测试,可以看出环境中卡的解码性能正常,fps 202,完全满足60fps的解码需求。这就排除的解码带来的延时考虑。

mpv参数介绍
mpv 参数很多,可以用list列出,并找出感兴趣的部分。
mpv --list-options |grep gpu--gpu-api String (default: )--gpu-context String (default: )--gpu-debug Flag (default: no)--gpu-dumb-mode Choices: auto yes no (default: auto)--gpu-hwdec-interop String (default: auto)--gpu-shader-cache-dir String (default: ) [file]--gpu-sw Flag (default: no)--gpu-tex-pad-x Integer (0 to 4096) (default: 0)--gpu-tex-pad-y Integer (0 to 4096) (default: 0)
由于解码好的,而又是本地视频文件,那么就剩本地存储设备与显示部分的问题。首先查看显示部分。
gpu-context参数
即窗口显示的上下文接口,支持如下几种。
mpv --gpu-context=help
GPU contexts (APIs):
auto (autodetect)
wayland (opengl) 这个不能用渲染 (报错误,不能加载libvdpau_gpu.so) VDPAU是另外一套开源接口。
x11egl (opengl) 这个参数在Gpu上可以用GPU渲染
x11 (opengl) 这个不能用GPU渲染
drm (opengl) 这个不能用GPU渲染
我们采用的显卡采用vaapi接口解码。实际测试上面几种,只有x11egl走的GPU 硬件渲染,而其他几个走的都是软件渲染。通过GPU及CPU占用率可以看出,正常GPU占12%,cpu40%多;而异常GPU占5%,而cpu 占120%左右。
![]()
同时对比故障机器视频,与软件渲染接口的视频,显示速率基本一致。那么肯定是由于此方面导致的了。
那么究竟是什么导致了这不同的流程呢?是某些软件的安装修改了某些环境变量导致的吗?
debug参数
--msg-level=all=debug
通过加载此参数,可以打印出mpv执行过程。
示例如下: 如下打印了mpv确定gpu context的过程:
(+) Video --vid=1 (*) (hevc 1920x1080 60.000fps)(+) Audio --aid=1 (*) (aac 2ch 48000Hz)
[vo/gpu] Probing for best GPU context.
[vo/gpu/opengl] Initializing GPU context 'wayland'
[vo/gpu/opengl] Initializing GPU context 'x11egl'
[vo/gpu/x11] X11 opening display: :0
[vo/gpu/x11] X11 running at 1920x1080 (":0" => local display)
[vo/gpu/x11] Detected wm supports NetWM.
[vo/gpu/x11] Detected wm supports FULLSCREEN state.
[vo/gpu/x11] Detected wm supports ABOVE state.
[vo/gpu/x11] Detected wm supports STAYS_ON_TOP state.
[vo/gpu/x11] Detected wm supports BELOW state.
[vo/gpu/x11] Display 0 (HDMI-1): [0, 0, 1920, 1080] @ 60.000000 FPS
[vo/gpu/x11] Current display FPS: 60.000000
[vo/gpu/opengl] EGL_VERSION=1.5
[vo/gpu/opengl] EGL_VENDOR=Mesa Project
[vo/gpu/opengl] EGL_CLIENT_APIS=OpenGL OpenGL_ES
[vo/gpu/opengl] Trying to create Desktop OpenGL context.
[vo/gpu/opengl] Chosen EGLConfig:
[vo/gpu/opengl] EGL_CONFIG_ID=13
[vo/gpu/opengl] EGL_RED_SIZE=8
[vo/gpu/opengl] EGL_GREEN_SIZE=8
[vo/gpu/opengl] EGL_BLUE_SIZE=8
[vo/gpu/opengl] EGL_ALPHA_SIZE=0
[vo/gpu/opengl] EGL_COLOR_BUFFER_TYPE=12430
[vo/gpu/opengl] EGL_CONFIG_CAVEAT=12344
[vo/gpu/opengl] EGL_CONFORMANT=77
[vo/gpu/opengl] Choosing visual EGL config 0xd, visual ID 0x21
[vo/gpu/opengl] GL_VERSION='4.0 build 1.0.32672715'
[vo/gpu/opengl] Detected desktop OpenGL 4.0.
现场debug日志
(+) Video --vid=1 (*) (hevc 1920x1080 60.000fps)(+) Audio --aid=1 (*) (aac 2ch 48000Hz)
[vo/gpu] Probing for best GPU context.
[vo/gpu/opengl] Initializing GPU context 'wayland'
[vo/gpu/opengl] Initializing GPU context 'x11egl'
[vo/gpu/x11] X11 opening display: :0
[vo/gpu/x11] X11 running at 1920x1080 (":0" => local display)
[vo/gpu/x11] Detected wm supports NetWM.
[vo/gpu/x11] Detected wm supports FULLSCREEN state.
[vo/gpu/x11] Detected wm supports ABOVE state.
[vo/gpu/x11] Detected wm supports STAYS_ON_TOP state.
[vo/gpu/x11] Detected wm supports BELOW state.
[vo/gpu/x11] Display 0 (HDMI-2): [0, 0, 1920, 1080] @ 24.000000 FPS
[vo/gpu/x11] Current display FPS: 24.000000
[vo/gpu/opengl] EGL_VERSION=1.5
[vo/gpu/opengl] EGL_VENDOR=Mesa Project
[vo/gpu/opengl] EGL_CLIENT_APIS=OpenGL OpenGL_ES
[vo/gpu/opengl] Trying to create Desktop OpenGL context.
[vo/gpu/opengl] Chosen EGLConfig:
[vo/gpu/opengl] EGL_CONFIG_ID=13
[vo/gpu/opengl] EGL_RED_SIZE=8
[vo/gpu/opengl] EGL_GREEN_SIZE=8
[vo/gpu/opengl] EGL_BLUE_SIZE=8
[vo/gpu/opengl] EGL_ALPHA_SIZE=0
[vo/gpu/opengl] EGL_COLOR_BUFFER_TYPE=12430
[vo/gpu/opengl] EGL_CONFIG_CAVEAT=12344
[vo/gpu/opengl] EGL_CONFORMANT=77
[vo/gpu/opengl] Choosing visual EGL config 0xd, visual ID 0x21
[vo/gpu/opengl] GL_VERSION='4.0 build 1.0.32672715'
[vo/gpu/opengl] Detected desktop OpenGL 4.0.
指定gpu-context参数
通过指定gpu-context可以采用确定的硬件渲染显示,进而规避环境中软件安装冲突带来的渲染显示通路选择问题。
mpv --gpu-context=x11egl --profile=low-latency --untimed=yes --cache=no ./1080p60-265.mp4
mpv统计信息
按键: shift +i 可以在播放窗口显示出当前播放视频的统计信息。
正常统计

异常统计

通过对比可以看出:
1) 我们采用了no cache的开关,但是有问题时,total cache 依旧有48M,超过总视频大小的一半。
2)两者都没有丢帧。
3) frame timings: 上一次,平均以及峰值,异常都是正常的3倍之多。
EDID信息及显示信息
两者完全一致

起初异常机器接一个显示器,后来接两个,但没有影响。

总结
播放视频的延时,从整个链路分析。而很多人聚焦在解码层,忽略网络(存储层)与显示层的问题。通过mpv的debug输出,我们可以对比正常异常的差异,更容易发现问题的所在。
