https://www.jianshu.com/p/7c03ebc0d2a0

Android 硬编硬解退坑指南

_qisen

2018.09.01 17:44 字数 2266 阅读 223评论 2喜欢 4

抖音、快手在国内迅速走红,也带动了国内短视频的热潮。短视频录制、编辑等等功能,是一项系统性、专业性很强的领域。经过一段时间发展后,有多种方式可以通向罗马,但并不是每一条路都好走。这篇文章将重点介绍下,硬编硬解过程中遇到的坑,也给读者朋友架构方案时提供一点参考。

原文链接: https://mp.weixin.qq.com/s/SqP-AcEh5EMbkVDP83cCrw


Camera 使用的坑

虽然和硬编硬解没有关系,但短视频客户端不可能绕过这个,这里也列举下我所遇到的问题。

API 使用上的一些坑

Camera API 是 Android 碎片化严重的体现,不同于 iOS 系列,一共就那几种机型。Android 厂商众多,ROM 也百花齐放,同样的 API 在不同机型上提现可能完全不同,也是我们需要在开发过程中留意的。下面简单列举两个可能会导致画面异常的 API。

  1. setRecordingHint

Sets recording mode hint. This tells the camera that the intent of the application is to record videos MediaRecorder.start(), not to take still pictures Camera.takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback). Using this hint can allow MediaRecorder.start() to start faster or with fewer glitches on output. This should be called before starting preview for the best result, but can be changed while the preview is active. The default value is false. The app can still call takePicture() when the hint is true or call MediaRecorder.start() when the hint is false. But the performance may be worse.

官方的注释如上,英文很简单,就不翻译了。看上去是一个很人畜无害的 API,但实际上却暗藏杀机。此方法需要你设置 video-size,如果不设置这个,将会在某些机型(OPPO A37f, MI 2 , LG 部分手机)上造成拉伸的后果。

图片来源于网络

RecordingHint 的目的是帮助更快速地进行录制,某些 ROM 在实现的时候,没有考虑到 Preview Size 和 Video Size 之间的区别,例如使用 480 * 864 的分辨率进行录制,输出的文件大小为 400 * 800,那么势必会使得整体画面出现拉伸的情况。

  1. setVideoStabilization

Enables and disables video stabilization. Use isVideoStabilizationSupported() to determine if calling this method is valid. Video stabilization reduces the shaking due to the motion of the camera in both the preview stream and in recorded videos, including data received from the preview callback. It does not reduce motion blur in images captured with takePicture. Video stabilization can be enabled and disabled while preview or recording is active, but toggling it may cause a jump in the video stream that may be undesirable in a recorded video.

官方文档上写着,这个方法可以帮助提高录制视频的稳定性。使用的时候通过 #isVideoStabilizationSupported 来判断是否可以使用。如果妄自使用的话,会造成页面黑屏,PreviewCallback 没有任何回调。这两个 API 都是官方文档中提及,但完全没有任何隐患说明的地方,Camera API 调用的坑可见一斑。

Camera 效果不一致

如果 UI 妹子对画面要求比较高,需要在各大手机品牌上取得一致效果,那对于 Android Developer 简直是一场灾难。例如同样的白平衡效果,在 google 旗舰机型 Pixel 2XL 与 Huawei Honor 的差异就很明显。一般对于 Android 端,我们不能强求一致的效果,而是要提供给用户足够的自由度,让他们在机器提供的能力范围内拍出较为满意的效果。

Oppo 的部分机型自带美颜效果,而其他较为老旧的机型则没有这样的功能,因而我们对于这些机型上的默认美颜处理可以有不同的策略。

并不是所有机型都对拍出的照片添加了 Exif 信息,所以我们不能默认照片都是竖直方向的。如果照片中含有 Exif,还是要根据这个来判断照片方向。

总结起来说,我们在使用 Android Camera API 时,需要对曝光、色温、快门这些基本的拍摄概念有一个了解,这样才能在遇到各种奇怪情况的时候找到合适的解决方案。


硬编硬解的若干坑

MediaCodec 不一定支持

首当其冲的就是 MediaCodec 不一定支持!特别是一些老旧机型比较突出,在引入 CTS 测试之前,那简直了(手动微笑)。建议在合适的地方,判断硬编硬解支持的程度。

这里列举出 CTS 中测试 MediaCodec 支持程度的链接,tests/tests/media/src/android/media/cts/EncodeDecodeTest.java - platform/cts - Git at Google,大家可以参考这其中的代码来判断用户机型的支持程度。 如果机型不支持,大概率在创建 Encoder 的时候就会崩溃。

Surface 也不一定支持

MediaCodec 支持的数据类型中,有一项就是 Surface。Surface 直接使用 native 层的 Buffer,这样避免映射和拷贝,效率上能高不少。然而并不是每一种机型都支持 Surface 格式的。

create inputsurface

我们可以在 createInputSurface 的时候 catch 下异常,如果代码上没有问题,那真的就是机型上不支持 Surface 了,那只能老老实实用 ByteBuffer 吧(手动扇子脸)。

虚晃一枪的 API

备注:笔者使用的是 Google Pixel 2XL (Version 8.1) 进行地测试。

编解码本身灵活性就相对欠缺,可配置的地方就少,但就算在这种情况下那些看上去不错的接口,很大概率上只是镜中月,水中花,梦里人。

  1. BitMode
    文档上写着三种支持三种码率模式,CQ的意思是尽量保证帧率,保证图片质量;CBR 则是尽量保证每一帧的码率,但在一些动作比较大的Video中,就很容易模糊;VBR 则是前两者之间一个中庸的方案。
    但是,绝大多数机型都只支持 VRB 一种。(如果有错误,欢迎指正)

    bit mode

  2. CodecLevel、CodecProfile
    设置这两个值,可以改变编码级别,不同编码级别得出的效果不一样,级别越高,效果越好。我们可以通过 ffmpeg,或者 mediaInfo 来查看视频的编码级别。笔者在 Pixel 2XL 支持的 level、profile 中,分别进行测试,发现所有视频编码出的效果,都是 Base Media/ Version 2。又一个并没有什么卵用的 API,笔者只能认为这是 Google 为日后埋下的伏笔了。同理 getComplexityRange 这个 API,可以有 low、upper两种级别,但它们的值都是0,可能 low 和 upper 是双胞胎吧(手动扇子脸)。

codec profile

隐式限制很多

MediaCodec 在 Configure 的过程中,可以设置各种各样的颜色格式。但实际上支持的种类非常有限,调用前一定要通过 getCapabilitiesForType来确认下。

一般来说,绝大多数相机的 Preview 输出都支持 NV21,因此我们在使用 Camera API 的时候,可以放心地在 Camera#Parameters setPreviewFormat 使用 NV21 格式。然鹅,MediaCodec 不一定支持 NV21 哦!这些支持的格式里面,不同厂商表现不一样哦,高通支持的别家还真不一定支持。底层在使用的时候,一定要做好判断。忘了说啦, getCapabilitiesForType这个 API 也要处理好异常(手动扇子脸 X3)。

写到这里,还需要额外指出一点,16位对齐的事情。软编软解的时候,可以放心使用 540 * 960 这样的分辨率,但在硬编硬解的时候,一定要用 544 * 960,如果没有16位对齐,才不说什么 MOTO 机型直接花屏给你看 的事情。


结语

出了上述的问题以外,其他 API 的限制(坑)都不少,例如 MediaMuxer 基本上和 MPEG-4 绑定死了。那这么说起来,硬编硬解在 Android 上是不是就不能用呢。其实也没那么不堪,在编解码速度上比软编软解快上不少,笔者简单进行了下对比,能快上50%(不具有参考性,机型越好,差距越少)。这里只是写一篇文章,分享下在实际开发中遇到的坑,给各位读者大大一点参考。


文档信息

  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 发表日期:2018年9月1日
  • 社交媒体:weibo.com/woaitqs
  • Feed订阅:www.woaitqs.cc/feed.xml

Android 硬编硬解退坑指南相关推荐

  1. 【短视频SDK】Android如何使用硬编硬解?

    为什么要使用硬编硬解? 音频和视频编码时有两种选择:软件编码和硬件编码.软编的效果更好但会占用更多的资源,硬编的效果差一些但占用的资源较少. 同样解码也有两种选择:硬件解码和软件解码.硬解的效果相比软 ...

  2. Android MediaCodec 音频转码——硬编硬解

    我本来是做Android的,但是来公司之后主要负责Android端的多媒体相关,很多有关音视频编解码的都没有接触过.刚开始有一个项目使用硬编硬解完成音频的转码,刚开始我连怎么用硬编硬解都不知道,所幸在 ...

  3. WebRTC[44] - WebRTC 在安卓端的视频硬编硬解策略详解

    目录 前言 正文 一.硬件加速编码 1.1 系统版本限制 1.2 工具库限制

  4. android file域,Android FileProvider详细解析和踩坑指南

    其实很早之前我的应用就已经兼容到Android7.0了,此次写这个文章就是想详细梳理一下android的文件系统,以及做一下FileProvider的解析. Android7.0 (N) 开始,将严格 ...

  5. MSELoss详解+避坑指南

    MSE均方损失函数应用: loss(xi,yi)=(xi−yi)2 loss(xi,yi)=(xi−yi)2 这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标. 很多的 lo ...

  6. android安装多个微信支付,android微信支付详解与坑

    要想在自己的APP中实现APP支付必须申请开通支付功能,这些按着文档来吧,我还是直接说Android中的问题吧. 一.签名 一定要在开放平台为自己的APP配置正确的包名和签名(签名:将APP打一个正式 ...

  7. Android硬编、硬解h264

    项目工程demo地址https://github.com/liluojun/PlayVideo demo包含硬编解h264.libyuv裁剪图像.opengles渲染yuv数据.ffmpeg解码裸h2 ...

  8. iOS VideoToolbox 硬编指南

    引言 调用系统 VideoToolbox 的 API 实现一个硬编很容易,仔细看看文档.了解 API 的使用实现一个基本功能相信难不倒大家.但实际工作中有许多细节,一不注意就会掉坑里,甚至有些系统性问 ...

  9. 音视频开发(六):MediaCodec硬编解流程与实践

    目录 MediaCodec介绍 工作原理和基本流程 数据格式 生命周期 同步和异步模式 流控 实践:AAC解码为PCM同步和异步的两种实现 一.介绍 Android底层多媒体模块采用的是OpenMax ...

最新文章

  1. NLP相关论文上新-2019
  2. ISA2006标准版安装及无人值守安装
  3. 人生苦短,我用python+vscode
  4. 我所理解的 Block
  5. [Linux]守护进程(精灵进程)
  6. python123安装教程_小白安装Python环境详细步骤!
  7. 嵌入式数据库与数据库服务器
  8. 清明节,如何用代码让网页变灰
  9. Android ViewPager 滑动监听事件
  10. 进程篇—进程整理(转)
  11. eclipse后台提示computing additional info的解决办法
  12. 23 模块代码编写基础
  13. SQLAlchemy 对象缓存和刷新
  14. 推荐几个设计师常去的优秀素材网站!收藏好哦!
  15. 用药安全,从娃娃抓起
  16. 000webhost提供 1500M免费空间 可绑顶级域名
  17. Netty 实现百万连接的难点和优化点
  18. el-tree对已知节点设置disable
  19. developer 开启双重验证 your appid needs to be updated
  20. Yuan先生博客-Django基础

热门文章

  1. swftools工具将pdf文件转换为swf文件
  2. 一起变装吧服务器维护,2016年12月29日服务器停机维护公告
  3. 学计算机学生笔记本电脑实用,适合学生用的笔记本电脑推荐
  4. 100分-态度决定一切
  5. NB-IoT系列协议--3GPP--Release 16--TS 36.300--总体描述;阶段2
  6. uni-app 项目笔记 基础配置及scroll-view左右滚动效果
  7. C语言中闰年的判断及打印了1000-2000年中的闰年
  8. java文件类型转换,java 文件类型转换
  9. 【数据分析框架】AARRR模型的数据指标体系
  10. 男版维密用高科技撩妹:要美体多喝水