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;
    }

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

相关文章
|
3月前
|
安全 Android开发 Kotlin
Android经典实战之SurfaceView原理和实践
本文介绍了 `SurfaceView` 这一强大的 UI 组件,尤其适合高性能绘制任务,如视频播放和游戏。文章详细讲解了 `SurfaceView` 的原理、与 `Surface` 类的关系及其实现示例,并强调了使用时需注意的线程安全、生命周期管理和性能优化等问题。
191 8
|
2月前
|
Java 程序员 开发工具
Android|修复阿里云播放器下载不回调的问题
虽然 GC 带来了很多便利,但在实际编码时,我们也需要注意对象的生命周期管理,该存活的存活,该释放的释放,避免因为 GC 导致的问题。
46 2
|
6月前
|
XML 存储 数据库
如何使用Android Studio创建一个基本的音乐播放器应用
如何使用Android Studio创建一个基本的音乐播放器应用
322 0
|
3月前
|
Android开发
Android中SurfaceView的双缓冲机制和普通View叠加问题解决办法
本文介绍了 Android 平台上的 SurfaceView,这是一种高效的图形渲染控件,尤其适用于视频播放、游戏和图形动画等场景。文章详细解释了其双缓冲机制,该机制通过前后缓冲区交换来减少图像闪烁,提升视觉体验。然而,SurfaceView 与普通 View 叠加时可能存在 Z-Order 不一致、同步问题及混合渲染难题。文中提供了使用 TextureView、调整 Z-Order 和创建自定义组合控件等多种解决方案。
178 9
|
4月前
|
编解码 开发工具 Android开发
Android平台RTSP|RTMP播放器如何实现TextureView渲染
本文介绍了在Android平台上使用TextureView进行RTSP和RTMP视频流渲染的技术背景和实现方法。TextureView相较于SurfaceView具备更高性能、更强功能性和更灵活的绘制方式等优势,但也有必须在硬件加速环境下运行和较高内存占用等局限。文中详细展示了如何在SmartPlayerV2工程中创建和配置TextureView,并通过代码示例解释了如何根据视频分辨率信息调整显示比例,以及处理TextureView的各种生命周期回调。此外,还列举了该播放器SDK支持的多项高级功能,如多实例播放、多种编码格式支持、硬解码能力等,旨在帮助开发者更好地理解和实现高性能的直播播放器。
|
4月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。
|
5月前
|
Android开发 开发者
Android经典面试题之SurfaceView和TextureView有什么区别?
分享了`SurfaceView`和`TextureView`在Android中的角色。`SurfaceView`适于视频/游戏,独立窗口低延迟,但变换受限;`TextureView`支持复杂变换,视图层级中渲染,适合动画/视频特效,但性能略低。两者在性能、变换、使用和层级上有差异,开发者需按需选择。
107 1
|
4月前
|
编解码 网络协议 开发工具
Android平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台为例,介绍下如何集成RTSP、RTMP播放模块。
186 0
|
6月前
|
API Android开发 UED
56. 【Android教程】媒体播放器:MediaPlayer
56. 【Android教程】媒体播放器:MediaPlayer
148 0
|
7月前
|
存储 数据库 Android开发