Apple,HLS,NAL_AUD,——像要求自己的孩子一样严格!

Apple产品系列中,使用HLS实现直播,HLS可以简单理解为HTTP+M3U8+TS。

一、问题引出

最近遇到一个问题,MP4文件转成TS后,在Apple上播放会有帧错乱现象(前后帧显示时来回跳),但在Windows下的播放器如VLC显示都没有问题。

二、初探

小武同学根据十几年的经验判断,第一感觉认为是DTS或PTS错乱导致,但通过分析后发现DTS和PTS显示正常。

Apple,HLS,NAL_AUD,——像要求自己的孩子一样严格!_第1张图片

I,B,P帧的时间戳都没有问题。

问题可能出在哪里了呢?伟大的架构师LiuQi同学使用FFMPEG把无法正常播放的TS流文件重新打包了一下(不做转码),发现播放变得正常了。好吧,开始比较两个TS文件的区别(b-1.ts为原始文件,c-1.ts为FFMPEG转封装后的文件)。

先用StreamAnalyzer看一下吧:

Apple,HLS,NAL_AUD,——像要求自己的孩子一样严格!_第2张图片

SPS和PPS完全一样。

再使用ElecardEye看一下:

Apple,HLS,NAL_AUD,——像要求自己的孩子一样严格!_第3张图片

Gop结构,Slice信息,也都没有问题。

搞了两天,不管是TS层面,PES信息,还是ES信息上都没有看出有什么区别,见了鬼了!

三、深入分析

看来得用最后的手段了,二进制比较。但从哪个层面比较呢?由内到外吧,先把ES内容剥出来比较一下。

照妖镜一出,小鬼无藏身之处,图中红色部分为原文件中多出的内容。

分析一下吧,00 00 00 01 09  E0,这是NAL_AUD吗(Access Unit Delimiter),访问单元分隔符,表示一个帧数据的结束,只是多一个结束就会导致显示错乱吗?试着把原文中多出的部分删除掉,显示果然正常了。

还是不解,为什么VLC显示没有问题呢?看一下FFMPEG中解码H.264的代码吧:

Apple,HLS,NAL_AUD,——像要求自己的孩子一样严格!_第4张图片

在FFMPEG的解码过程中,遇到NAL_AUD直接跳过,查找下一个NAL去了,如果连续两个就跳两次,所以不会有问题;但在Apple的播放器中,如QuickTime,会严格把每帧数据和帧分隔符进行配对。

 

四、总结

在上文中之所以出现了两个NAL_AUD,是因为进行MP4转TS时,代码中没有判断帧后是否已经有了NAL_AUD,而是直接在每帧后面添加了一个,对于要求严格的播放器来讲,就出问题,看来代码要严谨,来不得半点马马虎虎啊!

你可能感兴趣的:(Apple,HLS,NAL_AUD,——像要求自己的孩子一样严格!)