利用Surface实现跨进程播放器

4,539 阅读1分钟

播放器在渲染、解码不同质量的视频时会消耗不同程度的、相当可观的内存,为了保障主进程的内存有效分配,可以考虑将视频解码模块独立运行与一个新的进程中,渲染仍保留在主进程中。为了实现这一功能,可以利用android.view.Surface类及Service\TextureView实现跨进程的视频播放器。

1、TextureView

在主进程的UI线程中,设置TextureView的SurfaceTextureListener,在SurfaceTextureListener的onSurfaceTextureAvailable中new一个Surface对象,并将其传递给远程服务的客户端PlayerClient。有了Surface对象,PlayerClient才能通过Binder传递给远程服务端,远程服务端解码的视频帧才可以渲染到主进程的TextureView上。

new Surface(TextureView.getSurfaceTexture())
package android.view;
public class Surface implements Parcelable {
    ...
}

2、Service

由于客户端调用服务端的方法运行在Binder线程池中,而我们的播放程序需要运行在当前子进程的UI线程中,因此需要将Surface对象再次传递给UI线程方能正常播放。

3、播放器

参考android-BasicMediaDecoder,只需要修改MediaCodecWrapper.fromVideoFormat即可。

MediaCodecWrapper.fromVideoFormat(mVideoExtractor.getTrackFormat(i),surface);

4、运行结果

启动播放进程后,可以看到存在28964、30978两个进程,28964为渲染主进程,30978为解码进程。两进程分工实现了跨进程视频播放的功能。

从以上两图看出,28964为渲染主进程一直在运行,而解码子进程则被zygote新建了。