You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ffmpeg_develop_doc/iOS资料/音视频学习--iOS适配H265实战踩坑记.md

10 KiB

音视频学习--iOS适配H265实战踩坑记

1.背景介绍

熟悉webrtc都知道:谷歌的webrtc,默认不支持h265,毕竟涉及到很多专利的事宜,这中间的八卦就暂时不做探究。但是今天拿到一个IPC,该设备会发送H265数据,如下图所示,要做到兼容相关IPC,只能适配H265编解码了。所以最近熬秃了好几把头发就做了一下相关知识的学习,以下是自己的学习笔记,提供大家一个解决问题思路,由于iOS刚接触,同时H265调试经验也欠缺,很多都是一边查找资料,一边学习的,难免有处理不妥当之处,欢迎一起讨论学习,开发大神请绕行。

img

2.补充1H265编码特性

学习之前先了解一下H265的编码特性,有的放矢才能遇到问题及时排查。H265的经典编码框架如下图:

img

HEVC 的编码框架是在H26X的基础上逐步发展起来的,主要包括变换、量化、熵编码、帧内预测、帧间预测以及环路滤波等模块。相关内容推荐阅读万帅老师的书《新一代高效视频编码H.265/HEVC:原理、标准与实现》。

一般提到H265,都难免要和H264对比一番,以下是这次需求端要求适配H265的基本理论依据,如下表格:

img

理论上要直接适配一种编解码格式,肯定要学习相关理论,然后再做对应适配。然而时间紧张,任务繁杂,根本没有足够时间积累。想要有一个全面直观的认识,同时为了验证IPC是否正常,所以首先用VLC进行播放尝试:PC端确认该IPC可以通过 VLC进行监控,这时我们可以通过wireshark抓包,拿到第一手数据进行分析。通过抓包可以看出:1920*1080的视频流除了IDR数据帧大小略大,其他数据都是一个NALU单元就完成封装了,文件大小确实小很多。

接下来我们依次认识H265的封包和关键信息。

3.H265关键信息

通过相关抓包,可以看到整理结构如下图,包含了VPS,SPS,PPS, FU分片包,Trail_R的包等。

img

img

3.1VPS结构

VPS(Video Parameter Set, 视频参数集)依据ITUHEVC的标准文档,VPS的参数结构以及每一个条款的解释,很多大佬已经有写明了,HEVC来说自己还是小萌新在此不再累述,可以参考自己关注的一个大佬的博文:

imgA//blog.csdn.net/Dillon2015/article/details/104142144)

其抓包中VPS数据参数如下:

img

3.2SPS结构

SPS的内容大致包括解码相关信息,如档次级别、分辨率、某档次中编码工具开关标识和涉及的参数、时域可分级信息等。

其抓包中SPS数据参数如下:

img

3.3PPS结构

HEVC的图像参数集PPS包含每一帧可能不同的设置信息;其内容大致包括初始图像控制信息,如量化参数(QP,Quantization Parament)、分块信息等。即PPS包含了每一帧图像所用的公共参数,即一帧图像中的所有SS会引用同一个PPS;每张图像的PPS可能不同。详细介绍说明可以参考:

其抓包中PPS数据参数如下:

img

有了这些数据,至少可以解析出来该IPC支持的分辨率,profile,level等基本数据信息,为初始化做准备。

4.H265解封包

由上面信息可以知道H265的封包格式和H264基本上保持一致,也是通过NALU单元进行分装,不过不太一样的地方是 H265的NALU Header长度是2个字节,而 H264的NALU Header的长度是1个字节,所以解析时候需要进行移位操作,否则读取数据异常,导致包类型无法辨别(在这里踩了一个小坑,印象深刻)。

H26封包中NALU type主要类型如下图所示。由于不同厂家支持程度不一,本次适配过程中主要关注的几个类型包括:kTrailR(1),kIdrwRadl(1),kVps(1),kSps(1),kPps(1),kFU(1)等。

img

4.1FUNALU

当 NALU 的长度超过 MTU 时, 用于把当前NALU单元封装成多个 RTP 包,HEVC的FU单元的type值为49,具体组织结构如下:

img

FU Nalu相关解析代码如下:

img

4.2SingleNALU

单个 NAL 单元数据包只包含一个 NAL 单元,由一个有效载荷头(表示为 PayloadHdr)、一个有条件的16位DONL字段和NAL 单元有效载荷数据。

img

4.3AP NALU

HEVC封包另外一个种封包格式:聚合模式(Aggregation Packets,APs),主要为了减少小型 NAL 单元的打包开销,例如大多数非 VCL NAL 单元,它们的大小通常只有几个字节。AP 将 NAL 单元聚合在一个访问单元内。AP 中要携带的每个 NAL 单元都封装在聚合单元中。聚合在一个 AP 中的 NAL 单元按 NAL 单元解码顺序排列。

img

AP Nalu和Single Nalu相关代码解析如下:

img

当接收到每一个HEVC包之后,一次送到Jitterbuffer中,完成数据帧的重新组装和排序,必要时候进行数据矫正和重传操作,这是另外的技术,此处暂不做讨论。

5.H265 VideoToolBox解码

收到完整数据帧时候,VCM会依据时间戳一次获取相关数据,送解码器,iOS平台就是VideoToolBox解码了。这部分自己是小白,简单说明关键函数,大佬勿喷。

5.1ResetDecompressionSession

ResetDecompressionSession完成解码参数的构建,以及Session的创建。主要注意iOS支持的色彩是有差别的,设置时候需要明确是否支持,比如这次就设置了kCVPixelFormatType_420YpCbCr8BiPlanarFullRange类型。

同时在reset函数中注册callback函数,用于接收解码完成后的视频帧。

img

5.2decode

iOS VideoToolBox相关开发说明,可以参考

img

img

获取VPS,SPS,PPS相关数据,构建CMVideoFormatDescription相关数据;

img

5.3callback

callback函数用于接收H265解码数据,并用于送到显示端进行渲染的。

img

6.补充2 Annexb和AVCC格式转换

Android的硬解码接口MediaCodec只能接收Annex-B格式的H264数据,而iOS平台的VideoToolBox则相反,只支持AVCC格式。所以要进行一次转换,相关转换规则有大佬做了说明,可以参考

img

7.补充3iOS编解码错误说明

在调试iOS编解码过程碰到几个CallBack的错误,于是找了一下相关错误代码,常见的错误如下所示:

img

其中一个错误kVTVideoDecoderBadDataErr = -12909,该错误找了很多久,也查了很多资料,一直卡住2天,每天早出晚归,熬最深的夜,加最晚的班,我可怜的头发又少了好几根。RIP.

期间尝试各种办法验证确认:

(1)将所有数据包和数据类型打印;

(2)送解码前数据打印和保存;

(3)反复确认VPS,SPS,PPS数据内容;

(4)确认调用流程;

(5)查找githubdemo。

最后确认经过多次反复确认代码,验证裸流,比较大小之后,最后发现计算长度时候H265 NAL头计算错误,导致IDR帧无法正确解码,最后找到问题,一行代码解决问题。其实该问题在RFC7798中有说明,只是自己还是按照H264惯性思维处理,这也是基础知识不扎实的根本原因(不过回想一下好像本来也没有这块知识,惭愧,惭愧)。

img

题外话:排查问题过程很艰辛,最后一行代码处理完成,这是目前工作中很常见的,所以也是自己给新人,或者要入门音视频强调的一点:保持足够投入度,最好是兴趣驱动。《格局》一书中说:主动做事的收益,或许不会在一两天内显现出来但是长期坚持下来,主动做事的人,就能和其他人拉开距离。

扯远了,最后分享一下排查问题期间也查阅其他人调试过程发现的问题点,在此一起收集一下,方便后来者遇到问题可以快速查阅:

(1)比如,省流模式下解码失败

该文章提到一种思路:可以借鉴比较成熟的ijkplayer,对比流程和处理细节,查找得到解决办法。

(2)比如,解码器Session失效问题

该文章中提到,如果VideoToolBox返回码是 kVTInvalidSessionErr =-12903,也就是说解码器Session异常或者失效了。可以在收到该返回码时调用ResetDecompressionSession操作完成重置,再进行切换时就会正常了。该部分优化已经同步了,防止切换异常;手动狗头,感谢大佬。

(3)比如,annexB与hvcc转换异常问题

该Issue中提到,ios硬解h265 NALU失败,看了代码发现在vtbformat_init中对265从annexB=>mp4转换时需要使用ff_isom_write_hvcc,而不能重用264的ff_isom_write_avcc。两者区别还是比较多的,有兴趣的翻阅一下FFMPEG代码自行补充。

原文https://zhuanlan.zhihu.com/p/589832516