完成一个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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447176.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golomb及指数哥伦布编码原理介绍及实现

文章来源: https://www.cnblogs.com/wangguchangqing/p/6297792.html , 写的不错,转发出来。 2017年的第一篇博文。 本文主要有以下三部分内容: 介绍了Golomb编码,及其两个变种:Golomb-Rice和Exp-Golo…

解决ipfs 出现Error: can‘t publish while offline: pass `--allow-offline` to override的问题

原因 出现这个问题的原因是因为,ipfs未与公网上的节点相互连接,因此此时处于离线状态 使用场景 部署自己的博客,后期的改动,累计追加在同一个地址,这个地址是唯一的,也就是创建ipfs生成的ID号 步骤 1&…

安装ipfs-http-client出现constants@0.1.2 install: node build.js > index.browser.js错误的解决办法

错误截图 原先的命令 npm install --save-dev ipfs-http-client 修改后的命令 npm install --save-dev ipfs-http-client --unsafe-permtrue --allow-root

安装ipfs-api的命令变了,最新版的命令如下

原先使用的命令安装ipfs-api npm install --save-dev ipfs-api 现在使用的命令安装ipfs-api npm install --save-dev ipfs-http-client 官方文档 参考教程 官方文档

区块链相关问题 理解

本博客针对区块链的部分问题进行详解,希望帮助大家对于区块链有一个更好的理解 1,如果散布虚假交易,怎么整?(谁欠我XXX比特币) 1,可以发起虚假交易,但是很难被全网的节点接收并写入…

区块链的相关知识点

1,密码学原理 密码学原理 1,collision resistance 哈希函数 ,目前还是很安全的,没有找到任何不同的内容其哈希是一致的情形。哈希碰撞(这个在数学上面是没法证明的,都是日常的实践表明,无法找…

使用MAC 编译合约的时候报错:

编译报错的显示内容如下: Error: EACCES: permission denied, mkdir /Users/chy/Documents/ipfslearn/ipfs_eth_img/client/src/contracts 最简单的解决方法 原因分析:执行的权限不够 解决办法:升级权限 使用命令 chmod 777 项目的文件夹使…

最新,使用truffle框架之后,安装ipfs的api包文件的命令变化

原因 项目文件路径变化了,不是先前直接在项目文件夹里面直接执行安装ipfs的命令了,需要切换到client文件夹下面执行 路径不对,会出现错误,错误提示如下 切换到正确的路径之后,使用命令 npm install --save ipfs-http-…

通过node 完成简单的web3 API调用测试

使用命令查看当前web3的版本 npm list web3输入命令 node,进入终端 引入web3,使用命令 var web3 require(web3) 查看引入web3的版本 web3.version

LInux学习笔记(四)-----实操排雷

参考书籍:linux就该这么学 4 Vim 编辑器与 Shell 命令脚本 4.1 Vim 文本编辑器(在 Vim 中,无法直接从输入模式切换到末行模式) 4.1.1 配置 Yum 软件仓库 注:书中好像有点问题,第一个 . 改成 /(我是Ubuntu发现原来不能用…

Web3.js 学习

web3.js Web3 JavaScript app APIweb3.js是一个JavaScript API库,一般使得DApp在以太坊上运行web3.js通过RPC调用与本节点通信,用于任何暴露了RPC层的以太坊节点之间通信web3包含了eth对象,即web3.eth(专门和以太坊区块链交互&am…

c语言指针入门

指针的用途非常广泛,比如如果你想通过函数改变一个变量的值,就得用指针而不能用值传递。还有在很多时候变量,特别是对象的数据量实在太大,程序员就会用指针来做形参,只需要传递一个地址就行,大大提高了效率…

搭建基于飞桨的OCR工具库,总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别、竖排文本识别、长文本识别的PaddleOCR

介绍 基于飞桨的OCR工具库,包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别、竖排文本识别、长文本识别。同时支持多种文本检测、文本识别的训练算法。 相关链接 PaddleOCR项目地址飞桨开源深度学习平台效果展示页面中文OCR在线体验地…

macos 10.15 django2.2+apache2.4+ladon+wsgi写webseverice接口

他的文档不够完善,使用起来可能有坑,因为不知道如何将ladondjangoapache绑定在一起使用,所以放弃了。 提醒:最好用个虚拟环境,防止库冲突我使用的是anaconda 安装apache macos本身自带apache,其他平台百度…

基于HubServing的PaddleOCR部署

前提要求 服务器的部署需要鉴于先前安装配置的docker环境,因此相关步骤查看我之前的博客 参考链接 服务部署 先前介绍 参考链接 官方推荐本博客采用基于HubServing的部署,这种方式已经集成到PaddleOCR里面,在先前的docker镜像里面就可以…

我的职业生涯规划学习日记(软件工程)整理时间线

学习路线 语言只是工具不过学c一直都做不出来东西是为什么呢,下图要第六部才做项目 概述 大一上学期:C,C,数据结构,cstl源码,python爬虫进入物联网实验室python方向,进入算法协会运维部学习算…

PaddleOCR和ChineseOCR的对比

PaddleOCR和ChineseOCR的对比 ChineseOCRPaddleOCR 对比 识别时间 chineseOCR识别的速度相对于PaddleOCR较慢,单纯使用CPU对于单张图片的识别时间可以达到20秒,如果使用GPU识别的时间一般控制在5秒以内(图片包含的文字比较少的情形&#x…

C++内存管理(1)

根据侯捷老师的视频:https://www.bilibili.com/video/BV1Kb411B7N8 这篇文章归纳内存管理的面试题和一些知识点梳理 正在更新中 首先为什么想要内存管理 不知道有没有人好奇delete[]或者delete的时候为什么系统会自动这个变量 占了多少字节。 答案是因为cookies&a…

Linux学习笔记(一)------实操排雷

参考兄弟连b站网课 1.1如果没有ifconfig 使用sudo apt install net-tools 下载;(ifconfig已经被淘汰所以需要另外下载) 1.2如果网卡是ens33; (1). vi /etc/sysconfig/network-scripts/ifcfg-ens33 将里面的…

Dapp简单的投票小例子

准备工作 相关命令 mkdir simple_voting_dapp //创建文件夹cd simple_voting_dapp //进入文件夹npm init //初始化npm包管理文件,输入ls 可以看到创建的package.json文件npm intsall web30.20.1 //安装web3npm install solc0.4.25 //安装solcnpm install -g ga…