Android播放器之SurfaceView与GLSurfaceView

简介: Surface的官方介绍:Handle onto a raw buffer that is being managed by the screen compositor,Surface是一个raw buffer的句柄,通过它在raw buffer上进行绘制,可以通过Surface获得一个Canvas。

先看Surface

Surface的官方介绍:Handle onto a raw buffer that is being managed by the screen compositor,Surface是一个raw buffer的句柄,通过它在raw buffer上进行绘制,可以通过Surface获得一个Canvas。

Canvas canvas = mSurface.lockCanvas(null);
mSurface.unlockCanvasAndPost(canvas);

SurfaceView

SurfaceView对Surface进行了一次封装,它内部帮我们管理了一个Surface。我们使用SurfaceView其实最终都是获取到这个Surface去绘制,可参看官方解释:


Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen


The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.


The transparent region that makes the surface visible is based on the layout positions in the view hierarchy. If the post-layout transform properties are used to draw a sibling view on top of the SurfaceView, the view may not be properly composited with the surface.


Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by calling getHolder().


The Surface will be created for you while the SurfaceView's window is visible; you should implement SurfaceHolder.Callback#surfaceCreated and SurfaceHolder.Callback#surfaceDestroyed to discover when the Surface is created and destroyed as the window is shown and hidden.


One of the purposes of this class is to provide a surface in which a secondary thread can render into the screen. If you are going to use it this way, you need to be aware of some threading semantics:


   ●  All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread.


   ●  You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().


绘制过程:

  • 通过SurfaceHolder.getSurface可以获取到Surface;
  • 通过Surface.lockCanvas可以获取到Surface的Canvas;
  • 使用Canvas绘制图像;
  • 使用Surface.unlockCanvasAndPost可以释放Canvas。

GLSurfaceView

GLSurfaceView继承自SurfaceView,对SurfaceView又做了一次封装,方便我们在安卓中使用OpenGL。


GLSurfaceView提供了以下特性:


  • 提供并且管理一个独立的Surface;
  • 提供并且管理一个EGL display,它能让opengl把内容渲染到上述的Surface上;
  • 支持用户自定义渲染器(Render),通过setRenderer设置一个自定义的Renderer;
  • 让渲染器在独立的GLThread线程里运作,和UI线程分离;
  • 支持按需渲染(on-demand)和连续渲染(continuous)两种模式;
  • GPU加速:GLSurfaceView的效率是SurfaceView的30倍以上,SurfaceView使用画布进行绘制,GLSurfaceView利用GPU加速提高了绘制效率;
  • View的绘制onDraw(Canvas canvas)使用Skia渲染引擎渲染,而GLSurfaceView的渲染器Renderer的onDrawFrame(GL10 gl)使用opengl绘制引擎进行渲染。


参看官方解释:


An implementation of SurfaceView that uses the dedicated surface for displaying OpenGL rendering.


A GLSurfaceView provides the following features:


  • Manages a surface, which is a special piece of memory that can be composited into the Android view system.
  • Manages an EGL display, which enables OpenGL to render into a surface.
  • Accepts a user-provided Renderer object that does the actual rendering.
  • Renders on a dedicated thread to decouple rendering performance from the UI thread.
  • Supports both on-demand and continuous rendering.
  • Optionally wraps, traces, and/or error-checks the renderer's OpenGL calls.

总结

除了上述区别外,SurfaceView通用性更好,GLSurfaceView渲染更细腻,如果想让普通的SurfaceView渲染效果更好,可以加抗锯齿效果,不过抗锯齿效果会有一定的性能消耗,硬解码设置surface模式的话,直接用普通的SurfaceView。


一般兼容性比较好的播放器,会同时支持SurfaceView和GLSurfaceView两种模式供用户根据实际场景选择,以大牛直播SDK(Github)的Android平台RTSP和RTMP播放端为例:

    /* Create rendering */
    private boolean CreateView() {
        if (sSurfaceView == null) {
            Log.i(TAG, "CreateView..");
            String manufacturer = Build.MANUFACTURER;
            Log.i(TAG, "CreateView, current manufacturer: " + manufacturer);
            if (is_enable_hardware_render_mode) {
                //hardware render模式,第二个参数设置为false
                sSurfaceView = NTRenderer.CreateRenderer(this, false);
            } else {
                //这个字符串可以自己定义,例如判断华为就填写huawei,魅族就填写meizu
                if ("huawei".equalsIgnoreCase(manufacturer)) {
                    sSurfaceView = NTRenderer.CreateRenderer(this, true);
                } else {
                    /*
                     * useOpenGLES2: If with true: Check if system supports openGLES, if
                     * supported, it will choose openGLES. If with false: it will set
                     * with default surfaceView;
                     */
                    sSurfaceView = NTRenderer.CreateRenderer(this, true);
                }
            }
        }
        if (sSurfaceView == null) {
            Log.i(TAG, "Create render failed..");
            return false;
        }
        if (is_enable_hardware_render_mode) {
            SurfaceHolder surfaceHolder = sSurfaceView.getHolder();
            if (surfaceHolder == null) {
                Log.e(TAG, "CreateView, surfaceHolder with null..");
            }
            surfaceHolder.addCallback(this);
        }
        return true;
    }

感兴趣的开发者可以参考官方文档。

相关文章
|
7月前
|
缓存 网络协议 开发工具
庖丁解牛之-Android平台RTSP|RTMP播放器设计
我们在做Android平台RTSP或者RTMP播放器开发的时候,需要注意的点非常多,以下,以大牛直播SDK(官方)的接口为例,大概介绍下相关接口设计:
110 0
|
存储 缓存 前端开发
关于Android SurfaceView截屏总结
关于Android SurfaceView截屏总结
1448 0
|
7月前
|
开发工具 Android开发 iOS开发
Android、iOS平台RTMP/RTSP播放器实现实时音量调节
介绍移动端RTMP、RTSP播放器实时音量调节之前,我们之前也写过,为什么windows播放端加这样的接口,windows端播放器在多窗口大屏显示的场景下尤其需要,尽管我们老早就有了实时静音接口,相对实时静音来说,播放端实时音量调节粒度更细,从[0, 100],用户体验更好。
130 1
|
4月前
|
XML 存储 Java
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
43 0
|
7月前
|
编解码 网络协议 Android开发
Android平台RTMP|RTSP直播播放器功能进阶探讨
很多开发者在跟我聊天的时候,经常问我,为什么一个RTMP或RTSP播放器,你们需要设计那么多的接口,真的有必要吗?带着这样的疑惑,我们今天聊聊Android平台RTMP、RTSP播放器常规功能,如软硬解码设置、实时音量调节、实时快照、实时录像、视频view翻转和旋转、画面填充模式设定、解码后YUV、RGB数据回调等:
106 0
|
7月前
|
数据处理 开发工具 Android开发
Android平台RTMP/RTSP播放器开发系列之解码和绘制
本文主要抛砖引玉,粗略介绍下Android平台RTMP/RTSP播放器中解码和绘制相关的部分(Github)。
|
7月前
|
Android开发 开发者
Android播放器实现视频窗口实时放大缩小功能
很多开发者希望Android播放端实现视频窗口的放大缩小功能,为此,我们做了个简单的demo,通过播放端回调RGB数据,直接在上层view操作处理即可,Github:https://github.com/daniulive/SmarterStreaming
190 0
|
8月前
|
Android开发
Android 使用MediaPlayer和SurfaceView播放视频
Android 使用MediaPlayer和SurfaceView播放视频
68 0
|
9月前
|
编解码 Ubuntu Java
Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器
Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器
202 0
|
9月前
|
前端开发 安全 Android开发