8

完成一个H.265/HEVC码流分析工具

 1 year ago
source link: https://blog.csdn.net/china_video_expert/article/details/74217027
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

完成一个H.265/HEVC码流分析工具

经过大约一个月左右的业余时间,终于初步完成一个H.265/HEVC码流分析工具。时间包括平时的周末、晚上,以及调休的集中时间。当然,中秋回家过节不写代码。截至今天,经过多种H.265序列测试,也有各种工具对比,基本上无大问题,v2.0版本终于释放出来。v1.x版本是去年年初做的,弹指间一年多的今天又继续做。但后面也不知道有没有时间和心情完善,随缘吧。

按惯例,每年年中的时候,公司都要讲新平台预研,但不等预研结束,公司高层就开会举手敲定一个新平台,而使得“预研”结束。今年主题之一是上H.265。第一个H.265标准在2013年1月出来,至今不够3年时间,有很多公司盯上了这领域,势头很好,但毕竟只是开始的几年,还是有待发展。

这种宣传性的东西,估计产品经理、行业总监们要关注,咱们这些写代码的其实不用关心太多。但对于技术的研究、探索,还是很有必要的。网上已经有很多商用的工具开发出来了,在文章《初识HEVC/H.265》中提到一些。鉴于以前也写了H264码流分析工具,从这方面入手会好一些,一来练练手,保持代码熟悉度,二来在写的过程对照标准手册学习,效果比单看手册好很多。于是就在原来工具基础上,继续做H265的分析。

在文章《完成一个分析H264码流的工具》中大概写了一些思路,但不是很系统。这里再写一下。核心代码为h264bitstream开源库,它提供了一个很好的H.264码流读、写的方案,而且开源。它提供了基本的读写码流的接口。比如查找NAL,指数哥伦布编码等。因此,使用该开源库,只需根据标准手册里的语法规定去一一解析即可。关于这个库,不在此处详细展开描述。

0、根据标准手册语法,建立全局结构体,每个字段都单独存储。所有结构体归属于h264_stream_t和h265_stream_t结构体。对于数量不确定的字段,统一使用vector存储。

1、用户打开文件时,先判断文件类型,目前只支持H.264和H.265两种格式,如有后缀名,优先使用后缀名判定,否则读取文件开始处的NAL头,查看手册,两种码流的NAL头有差异,故可以使用该种方法。

2、按字节读取文件,根据start code解析NAL,得到NAL偏移量、长度、类型(如果是slice,还会解析出slice的类型,如I帧、P帧、B帧),存储于vector中,同时,为了得到如视频分辨率,帧率、YUV空间等信息,在解析NAL时,一并进行。做这些工作,是为了在界面的列表中列出各个NAL信息以及视频的概要信息。详见下文的界面截图。

3、鼠标双击某一个NAL时,根据前面得到NAL索引、偏移,读取文件并解析,从而得到该NAL详细信息,这里使用的方法,就是根据手册,逐一读取码流。

此处讲述一下在编码、学习过程的经验。

未动手写代码时,去下载商业工具玩玩,但只有几天的试用期,就把几个关键的NAL截图保存起来,方便日后对比。后面过期了,就拿HM的工程做对比,该工程打开几个宏就可以把运行过程的信息打印出来,包括解析码流的各个字段。

然后按手册的语法,参考h264bitstream代码,建立H.265的对应结构体,基本上语法大的方面保持一致,但H.265多了一个VPS结构体,还有ptl(profile tier level)。添加这些语法,耗时很多,一来语法字段本来就多,二来要对着手册看——即使这样,后面还是发现有个别错误、疏漏的。H.264/H.265有很多字段是属于数组类型,根据某一数值来确定范围。起初参考h264bitstream,数组统一使用255,但后来想想还是用Vector好一些,就改了。

读取码流完成了,打印字段也完成了,再从宏观上看整个工程,发现写有乱。这次是在去年写的工具上进行的,其实改善空间很大,只是自己懒,不去做。于是趁机会把代码重构了,重构后条理性好了很多。

之后就进行调试。在这个过程,还是有不少问题。

有些是细节问题,比如有个地方判断B帧,结果把“==”写成“=”,查了半天才发现。还有一个地方是pred_weight_table的判断,判断P和B帧的条件不同,但代码复制时不注意,没搞对,又花了很久排查。还有一个是读取slice头部的num_ref_idx_l1_active_minus1字段,同样是代码复制,没有注意是ue(),在和HM代码运行结果对比时,花了很多时间才确定问题。

打印NAL字段函数里,有些不按语法上写,导致个别字段和其它工具的不一致,于是又对着手册改——开始时就应该如此,又是懒没用心写。

下面说说其它的问题。

解析NAL,是要将码流转换成RBSP,代码工程统一使用h264bitstream提供的nal_to_rbsp函数,但该函数只针对只有一个字节的H.264码流的,而H.265的NAL头有2个字节。在转换时是不包括NAL头的,于是就手动修改该函数的参数。

关于SEI,h264bitstream库并没有做过多解析。或许是SEI信息重要程度不高吧。还有一个问题。在PPS中,more_rbsp_data的判断不正确。导致后面的字段不再解析。几经搜索,最终使用FFMPEG代码的判断方法,似乎是正常的了,就不再深究。

而至于其它的修改、完善,我在另一篇文章《关于h264bitstream的bug修正及完善》里写了,这里不再写出了。

无论怎样,还是完成了。此事务算告一段落。界面如下:

李迟作品 必属精品

源代码仓库地址为:https://github.com/latelee/H264BSAnalyzer。后续不确定是否要继续维护、更新,以仓库代码为准。

后记:调休期间,有传言说大大boss拍板停止调研某国产的支持H.265的芯片平台,但我没有在正式场合得到信息,不懂是否真实。在不确定是否上H.265时,我决定搞这个工具,在不确定是否停止H.265时,完成这个工具。有始有终。

2015.11.21的更新:

发布v2.1版本。使用树形控件显示码流语法元素。增加界面的缩放功能。离上个版本有差不多2个月了,理论上搞这么个小功能不用花那么久的,主要还是因为自己懒,一到周末就完全不想写代码了。新版本界面如下(一眼看上去,顿时觉得高端好多):

H265码流分析工具v2.1版本--latelee.org

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK