iOS h.264裸流分析

1.视频流 H264 分析

网上有不少的对裸流H264解码得到buffer,再用OpenGL渲染的demo。可是,h264这块的坑 不单单是一个demo或者几个demo能给你解决的。 首先,你必需要了解h264裸流的结构,才能一步一步填坑。ios

首先说说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。 取后一个字节的后四位,做为判断该帧为何类型(该帧的数据为两个界定符之间的数据)。视频

帧类型有:io

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端,后台又一直出差。多加了字节也没跟我讲。我是将裸流存为文件,一个帧一个帧的分析才发现的,为了解决这个问题,走路眼前出现的都是这些十六进制数字,若是你们碰到报这种错,能够试着将裸流保存成文件,而后再跟服务器推流的数据作比较,或者将裸流用工具进行分析,相信很快就能找到问题的源头。

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

你们有什么问题,能够在评论区评论,我看到了会尽力帮助你们。