硬解码H264黑屏的问题

982 阅读2分钟

「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战

硬解码H264黑屏的问题

有一个硬解码h264的项目,在播放H264码流时,同时切换app或者将app退出后台,会出现几秒种的黑屏,本篇文章针对这个问题做一种解决方案。

现象

应用程序在播放时,只要进入后台,再返回,就会黑屏几秒,几秒后播放正常。

原始代码思路

SurfaceView作为显示图像的载体,在SurfaceView创建成功时初始化解码器,用TCP接收H264码流,接收到的码流通过解码器解码并显示在SurfaceView上。

很简单的逻辑,也没什么问题,但是测试后发现,应用程序置于后台时,总有几秒种的黑屏。

尝试去搜索资料,发现大家都不用SurfaceView作为显示的载体了,而使用另外一种TextureView进行显示。看见大家都用TextureView去作为显示载体之后,控制生命周期不进行释放,才恍然大悟。

参考地址:
Android 使用MediaCodec实现视频的无缝切换
SurfaceView和MediaCodec搭配使用退到后台黑屏的问题(应用切换等情况)

解决办法

出现问题的根本原因是因为 在后台之后,会销毁surface

所以我们需要控制不被销毁,不释放。

我们使用TextureView来作为显示视图的组件,它可以设置生命周期的监听setSurfaceTextureListener,实现TextureView.SurfaceTextureListener这个接口后,拿到下面的回调方法,重点逻辑就在回调方法中。

 @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        // 生效
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
       // 改变
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
       // 销毁
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
     // 更新
    }

应用退出后台时,会执行onSurfaceTextureDestroyed的回调方法,在该方法中

mSurfaceTexture = surface

mSurfaceTexture 是全局变量

应用回到播放界面时,会执行onSurfaceTextureAvailable方法,在该方法中

if(mSurfaceTexture != null){ mTextureview.setSurfaceTexture(mSurfaceTexture);

将MediaCodeC和显示载体绑定
使用SurfaceView时是这样进行绑定

mCodec.configure(format, mSurfaceView.getHolder().getSurface(),
                    null, 0);

使用TextureView


mCodec.configure(format, getSurface(),
                    null, 0);
 ...
 public Surface getSurface() {
        if (mSurface == null) {
            mSurface = new Surface(mTextureview.getSurfaceTexture());
        }
        return mSurface;
    }