GLSurfaceView + libmpv播放视频仅显示单色闪烁问题求助
问题:GLSurfaceView + libmpv 视频有声音但屏幕单色闪烁
背景
- 最初使用
SurfaceView+ Android默认MediaPlayer播放视频,完全正常 - 改用
GLSurfaceView+MediaPlayer,未出现问题 - 切换为
GLSurfaceView+ libmpv后,能听到视频声音,但屏幕仅显示单色闪烁
当前使用的着色器代码
顶点着色器
uniform mat4 uSTMatrix; attribute vec4 aPosition; attribute vec4 aTexCoord; varying vec2 vTexCoord; void main(){ vTexCoord = aTexCoord.xy; gl_Position = aPosition*uSTMatrix; };
片段着色器
#extension GL_OES_EGL_image_external : require precision mediump float; varying vec2 vTexCoord; //uniform mat4 uColorMatrix; uniform samplerExternalOES sTexture; void main() { // gl_FragColor = uColorMatrix*texture2D(sTexture, vTexCoord).rgba; gl_FragColor = texture2D(sTexture, vTexCoord).rgba; };
解决思路
1. 核对纹理类型匹配
片段着色器使用的samplerExternalOES是适配Android SurfaceTexture的外部纹理类型,但libmpv默认可能输出普通2D纹理。可以尝试两种调整:
- 配置libmpv输出到
SurfaceTexture(需设置对应参数) - 把片段着色器的纹理类型改为
sampler2D,并移除#extension GL_OES_EGL_image_external : require语句
2. 修正矩阵乘法顺序
OpenGL采用列主序矩阵,顶点着色器中gl_Position = aPosition*uSTMatrix的顺序错误,正确顺序应为uSTMatrix * aPosition。顺序错误会导致顶点坐标变换异常,可能出现全屏单色或显示区域异常。
3. 检查libmpv渲染配置
确保libmpv的核心参数配置正确:
- 设置
vo=gpu指定GPU渲染输出 - 正确绑定GLSurfaceView的Surface或EGL上下文,确保渲染操作在GL线程执行
- 确认
surface_size参数与GLSurfaceView的分辨率匹配
4. GPU调试(Renderdoc)
用Renderdoc捕获渲染帧,重点检查:
- 纹理内容:是否有正常的视频帧数据,还是单色/空纹理
- Uniform变量:
uSTMatrix的数值是否合理,是否存在缩放、偏移错误 - 顶点数据:顶点坐标是否覆盖整个屏幕,避免绘制区域异常
5. 线程与上下文同步
GLSurfaceView的渲染线程与libmpv的操作线程必须同步,确保所有libmpv的渲染相关调用都在GLSurfaceView的onDrawFrame回调或同一个EGL上下文环境中执行,避免上下文冲突导致纹理无法正常绘制。
6. 日志排查
- 开启libmpv调试日志(设置
log-level=debug),查看是否有纹理创建失败、渲染错误的信息 - 在OpenGL关键步骤(程序链接、纹理绑定、绘制后)调用
glGetError(),并输出到Logcat,排查OpenGL错误码
内容的提问来源于stack exchange,提问作者Virtroid
相关产品推荐
相关产品推荐

