当前位置: 首页 > news >正文

「Android音视频编码那点破事」序章

  本章仅对部分代码进行讲解,以帮助读者更好的理解章节内容。本系列文章涉及的项目HardwareVideoCodec已经开源到Github。目前已迭代多个稳定版本,欢迎查阅学习和使用,如有BUG或建议,欢迎Issue。

封面出自:板栗懒得很

  其实这一两年关于Android 平台的视频编解码学习资料已经很多了,包括书籍和网上的一些公开教程。书籍讲得详细一点,所以推荐大家去买些书籍看看。而网上的资料的话,大多是零星点点,新手学习起来并不是很轻松,包括我。所以这也是促使本人对这一块知识做记录的原因。
  我打算开几个章节来分享一下相关的知识点,因为想详细展开,内容可能有点多,也算是做一些个人笔记。

  这个笔记的主要内容是,使用硬编和软编的方式解决Android视频编解码的问题(后续会支持解码),并且使用OpenGL实现滤镜渲染,包括美颜,水印等等。
  该项目已经开源在Github,目前已经迭代到了1.2.1版本,使用GPL开源协议,请大家遵守该协议,为开源事业做点贡献。名字虽然叫做硬编解码器,但其实已经扩展了软编。HardwareVideoCodec使用Kotlin实现,没有学过Kotlin的不需要害怕,先去看一些语言基础就可以了。


知识点

  • OpenGL

  1. EGL(全称Embedded Graphics Library,一组OpenGL连接本地窗口的接口,主要通过Surface向窗口绘制帧画面,以及给MediaCodec提供帧数据)

  2. FBO(帧缓冲区,这里主要用于离屏渲染以及特效)

  3. PBO(像素缓冲区对象,可以高效读取GPU中的像素数据,用于软编)

  4. 纹理

  • Camera

  • SurfaceTexture(集成了EGL环境的Surface,可以很方便的与OpenGL联动,也是TextureView提供的渲染接口)

  • MediaCodec(硬编解决方案)

  • X264(软编解决方案)

  • MediaMuxer(音视频混合器)

  •   以上内容我会选一部分在接下来的时间里详细展开,尤其是OpenGL和编码那一块。

    可能有人有疑问,软编解码首选的不是大名鼎鼎的ffmpeg吗,为什么直接使用x264。这里我可以很负责任的告诉你,直接使用x264,再配合MediaMuxer使用会简单很多,也是因为硬编同样会用到MediaMuxer。

      大家都知道ffmpeg其实就是在众多编解码器上套个壳子,再集成一个混合器,虽然功能众多,但是却很臃肿(当然已经很出色了),以至于我来了来来回回学习了4+次也没有掌握。ffmpeg的头文件相当多,相比之下,x264只有一个头文件,没几个方法,掌握起来很容易。对于编解码常常用到的颜色格式(ColorFormat)转换,ffmpeg提供了swscale,功能虽然很强大,但效率不敢恭维,完全可以使用google的libyuv替代。所以,如果没有很复杂的功能需求,还是老老实实的使用x264来的方便。

      先简单看一下HardwareVideoCodec的结构图:

            从结构图中可以看到,HardwareVideoCodec做了比较详细的分层结构,从上往下总共四层

    • 总控制器

    • 帧渲器

    • 编码器

    • 混合器
        可以很方便的进行扩展,比如把混合器去掉,在编码器数据出口处增加直播推流都是很方便的。

    • CameraPreviewPresenter:名字虽然叫做摄像头预览管理器,但其实也有统筹渲染器、编码器、混合器职能。在这个层级会持有摄像头,并且初始化一组EGL,提供取出摄像头数据的环境。

    • Render:摄像头数据在这里取出,并保存在第一组FBO。同时这一层的EGL环境会把FBO的数据绘制到TextureView提供的SurfaceTexture,也就是屏幕。这里还有一组filter,OpenGL的滤镜入口在这里。

    • Encoder:音视频编码器的抽象层,利用这组接口可以很方便的扩展自己的编码器。当然,笔者在这里已经提供了软硬编码器的实现。

    • Muxer:混合器,用来混合音视频,并把它们封装成需要的格式,这里固定封装成mp4。
        以上是HardwareVideoCodec的简单结构,作为序章就先讲这么多。接下来我会继续更新,详细去讲解具体实现,以及在实现过程中会碰到的一系列问题。有兴趣的可以去Github上查看源码学习,欢迎star以及issue。也可以关注我简书,以便能及时收到这个系列的更新。


    技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。

    推荐阅读:

    Android JNI Crash定位步骤

    Android JNI 之 Bitmap 操作

    Google Jetpack 新组件 CameraX 介绍与实践

    喜欢就点个「在看」吧 ▽

相关文章:

  • Android短文:理解插值器和估值器
  • 用户调研:音视频方面的书籍,哪些内容才是你需要的?
  • 职场PUA到底有多可怕?
  • Fragment 的过去、现在和将来
  • 数字图像处理领域中常见的几种色彩模式
  • Android VSYNC (Choreographer)与UI刷新原理分析
  • Android 实现 图片 转 字符画 效果
  • Android 实现 视频 转 字符画效果
  • 在 iOS 上用 Shader 实现 图片 转 字符画 效果~~
  • 【每周一记-003】~~~
  • Android Canvas 绘制小黄人
  • OpenGL ES 之 LUT(滤镜基准图)
  • Android开发第5年做了一个产品,被黄晓明,angelbabay,黄渤等一线明星转发后,我.........
  • FFmpeg 获取 视频首帧 转 封面图Bitmap
  • Java 与 JNI 互传数据的那些事
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • HashMap剖析之内部结构
  • Joomla 2.x, 3.x useful code cheatsheet
  • Mithril.js 入门介绍
  • mockjs让前端开发独立于后端
  • PaddlePaddle-GitHub的正确打开姿势
  • swift基础之_对象 实例方法 对象方法。
  • Vue 2.3、2.4 知识点小结
  • 阿里云Kubernetes容器服务上体验Knative
  • 创建一个Struts2项目maven 方式
  • 对象引论
  • 基于web的全景—— Pannellum小试
  • 使用 @font-face
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 正则表达式小结
  • 回归生活:清理微信公众号
  • ​比特币大跌的 2 个原因
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #传输# #传输数据判断#
  • #在 README.md 中生成项目目录结构
  • (09)Hive——CTE 公共表达式
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (C)一些题4
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (三)c52学习之旅-点亮LED灯
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (一) springboot详细介绍
  • (转)【Hibernate总结系列】使用举例
  • (转)c++ std::pair 与 std::make
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET 命令行参数包含应用程序路径吗?
  • .NET开源项目介绍及资源推荐:数据持久层
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递