市面上有很多种H.264硬压采集, 海康/大华/等等等等
找了半天发现所有的卡接口及其相似,在开发包中都是使用 RegisterStreamDirectReadCallback 注册回调函数来获取压缩后的数据流。
在它的回调函数中输出的码流不知道是啥子格式,而我需要标准的H.264码流,保存成flv并同时使用RTMP发布。如果解码后重新编码加重了CPU的负担,不符合要求。难道这就是传说中的海康码?
找啊找啊找啊找,在几乎绝望的情况下发现大华的工具里面居然有一个将 采集卡的录像文件 转换成 标准AVI 的小工具 StreamToAVI.exe。
马上一试,输出的AVI能够被MediaInfo识别,且显示AVI容器的 codec 是 AVC, Main profile. 哟西,看来还是标准的H.264码流啊。
只要能够反向这个工具就能够解析出可爱的NALU了。
打开IDA,首先盯上的就是ReadFile API调用
每次读取长度为0x10000 的文件块到内存,然后就call sub_401E30进行处理, 看来 401E30这个函数就是要反向的目标
这个函数是某个类的成员函数,成员变量是由ebp寄存器(this指针)加上偏移量进行操作,看起来真头疼啊
理清类的内存布局以及推测其中某些变量含义,花了3天时间, 虽然人是笨了点,不过好在有耐心。再结合调试跟踪,又花了一个周末的时间摸清了基本的来龙去脉。终于搞出点东西来了!
这个1FD 1FC 1FB 1FA 1F0 应该是类型字段,标明当前的数据类型
1F0 是音频编码,略过, 不感兴趣
1FD 和 1FC 是 H.264编码 , 1FD应该是 I帧
1FB 和 1FA 不知道是什么,调试中发现, 我的录像文件从不进入这个分支执行,它应该是另一种编码类型(0x3447504D?),可能是为其它某种型号的硬件准备的。这个就略过了,反正没用。
在0x403030处发现一个重要函数
这个函数的特征太明显了,连续设置0x00 0x00 0x00 0x01 以及 连续2个零后小于3做处理。
一眼就认出0x40303这个函数肯定是转换成H.264 Annex B format输出
围绕这个函数分析,发现卡输出的H.264分2种, 一种就是H.264 Annex B, 还一种就是普通的NALU
试着自己写了个解析程序,成功地转换了录像文件。
明天继续,离球门不远了 :)