iOS h.264裸流分析

来源:互联网 发布:能离线翻译软件 编辑:程序博客网 时间:2024/06/06 05:32

1.视频流 H264 分析

网上有很多的对裸流H264解码获得buffer,再用OpenGL渲染的demo。但是,h264这块的坑 不仅仅是一个demo或者几个demo能给你解决的。 首先,你必须要了解h264裸流的结构,才能一步一步填坑。

首先说说h264裸流的结构

例如: 

00 00 00 01 67 42 C0 28 DA 01 E0 08 9F 96 10 00 
00 03 00 10 00 00 03 01 48 F1 83 2A 00 00 00 01 
68 CE 3C 80 00 00 01 06 05 FF FF 5D DC 45 E9 BD 
E6 D9 48 B7 96 2C D8 20 D9 23 EE EF …

这是一段真实的码流。

每帧的界定符为00 00 00 01 或者 00 00 01。 取后一个字节的后四位,作为判断该帧为什么类型(该帧的数据为两个界定符之间的数据)。

帧类型有:

NAL_SLICE = 1 非关键帧 
NAL_SLICE_DPA = 2 
NAL_SLICE_DPB = 3 
NAL_SLICE_DPC =4 
NAL_SLICE_IDR =5 关键帧 
NAL_SEI = 6 增强帧 
NAL_SPS = 7 SPS帧 
NAL_PPS = 8 PPS帧 
NAL_AUD = 9 分隔符 
NAL_FILLER = 12

在ios硬解中,要将该帧转换成MP4风格的buffer,再放入解码器。

例如 上面的数据中 
67 42 C0 28 DA 01 E0 08 9F 96 10 00 00 03 00 10 00 00 03 01 48 F1 83 2A 
这是一个sps 
要在前面加入4个字节的大端 表示sps的长度 即 
00 00 00 18 67 42 C0 28 DA 01 E0 08 9F 96 10 00 00 03 00 10 00 00 03 01 48 F1 83 2A 
00 00 00 18 表示sps的长度 24

这些网上都能找的到。在此就不赘述,大概清楚就OK。

踩过的坑: 
1.模拟器可以解码,但是真机却不能解码。

解决:后台在每帧的裸流后面加了一个字节,判断是否是关键帧。导致真机报-12911错误,模拟器因为采用的是电脑的处理器,处理机制更为强大,所以没有太大影响。(注:如果你在解码过程中碰到-12911错误,赶快检查一下你的数据是否正确吧,当然,如果你的sps,pps没有配置对,也是会出现这个问题的)

2.模拟器正常解码,真机出现一般绿屏

解决:首先,我们需要知道绿屏现象是怎么产生的,绿屏是因为解码器少解了关键帧。要记得:丢I帧,绿屏。丢B、P帧可能会卡顿。分析h264裸流。发现这段裸流跟用h264硬编然后推流出来的裸流不一样。一个frame有多个slice,比如一个I帧,服务器在软编的时候分成了几份传给你(这是需要算法支持的,如果你要通过算法将这些分开的nal重新组合成一个完整的,目前我没有找到合适的办法)。你按照之前的解码方法,一个一个丢到解码器里面,解码器以为你的I帧是完整的,但其实只有一部分。所以导致出现一半绿屏的情况。解决方法就是将裸流中的数据重新打包成一个完整的帧,再送到解码器里面解码。这点还是比较麻烦的。在此就不贴代码了。需要的朋友可以私聊我,找我要。

这两个问题算是困扰我很长时间的。第一个问题说起很简单,但是因为这个项目我是从零开始iOS端,后台又一直出差。多加了字节也没跟我讲。我是将裸流存为文件,一个帧一个帧的分析才发现的,为了解决这个问题,走路眼前出现的都是这些十六进制数字,如果大家碰到报这种错,可以试着将裸流保存成文件,然后再跟服务器推流的数据做比较,或者将裸流用工具进行分析,相信很快就能找到问题的源头。

最重要的,还是多多熟悉裸流的结构,才是解决问题的根本。

大家有什么问题,可以在评论区评论,我看到了会尽力帮助大家。





原创粉丝点击