IOS平台统一使用HLS协议,包括M3U8文件和分段TS文件
现象:播放中画面动作抖动,好像画面的顺序错乱
范围:Mp4文件转成TS,没有问题,ASF转成TS文件,有该现象
原因:ASF没有cts_delta字段,TS(PES)中的PTS直接使用DTS,H.264中帧的顺序是DTS顺序,与显示顺序是不同的,B帧会出现在P帧前面,但是在后面显示
方案:自己根据帧率和帧的顺序,计算PTS,或者恢复出cts_delta值
帧率可以通过SPS中获取:
frame_rate=sps.vui_parameters.num_units_in_tick.time_scale/sps.vui_parameters.num_units_in_tick
当然前提是sps.vui_parameters_present_flag&&sps.vui_parameters.timing_info_present_flag&&sps.vui_parameters.fixed_frame_rate_flag
前提不满足的时候,可以用前后两个帧的dts差来计算:
frame_rate=time_scale/dts_diff
帧的顺序在每个帧内部有字段表示,根据sps.pic_order_cnt_type有不同算法,现在只考虑sps.pic_order_cnt_type==0的情况,这时候slice.slice_header.pic_order_cnt_lsb表示顺序
cts=(dtsofidr)+slice.slice_header.pic_order_cnt_lsb/2*time_scale/frame_rate
或者直接使用num_units_in_tick:
cts=(dtsofidr)+slice.slice_header.pic_order_cnt_lsb/2*sps.vui_parameters.num_units_in_tick
现象:播放过程中声音异常,夹杂着轻微爆炸的声音
范围:Mp4文件转成TS,没有问题,ASF、FLV转成TS文件,有该现象
原因:ASF、FLV时间戳是毫秒级精度,TS文件是90000分之一秒,相差90倍,直接乘以90转换,精度不够。IOS播放TS的时候,完全依赖TS时间戳。
比如采样率22050的音频,1024的采样点一个Sample,那么前三个Sample的时间戳情况是:
Sample号 | 精确时间戳(秒) | ASF时间戳误差 | TS时间戳误差 |
0 | 0 | 0 | 0 |
1 | 1024/22050 | -0.0004399 | 0.000004535 |
2 | 2048/22050 | 0.0001202 | -0.000002041 |
方案:自己根据采样率计算TS的时间戳,问题完整解决。
音频samplen的TS(PES)时间戳为n*90000*1024/采样率
备注:一开始没有找到这个原因,采用合并音频帧的方法,几十个音频帧合并起来,基本能解决问题,其中原因是合并之后误差减少,用上面的原因分析也是说得通的。
现象:播放刚开始,会出现瞬间绿色画面
范围:播放某几个文件时;有时正常从头播放没有绿屏,但是从中间继续播放会有绿屏。
原因:问题焦点集中在SEI的位置,Mp4只有第一个帧有SEI(只在第一个分段Mp4中有SEI),该帧的格式是:SEI+ISlice(IDRNalu),是同步帧。老版本bento4生成PES结果是AUD+SEI+SPS+PPS+ISlice(IDR);新版本版本bento4生成PES结果是AUD+SPS+PPS+SEI+ISlice(IDR)。虽然新版本有改动,也不能解决绿屏问题,还需要进一步分析。
方案:
现象:播放器直接crash掉
范围:MacOs平台,播放某几个文件时,在一个特定时间点。iphone、ipad并没有问题,但是同一影片同一时间点,会有播放丢帧现象
原因:问题本质上在于媒资压片(用Mp4Box生成Mp4文件)生成了不合常规的帧格式,在一个帧中出现了两个slice:PSlice+ISlice(IDRNalu),该帧不在Mp4同步帧索引中,因此不算是同步帧。老版本的bento4生成PES的策略是在每个帧前面加上AUD,在IDR前面增加SPS、PPS,所以转换结果是AUD+PSlice+SPS+PPS+ISlice(IDR);新版本的bento4生成PES的策略是在每个帧前面加上AUD,在同步帧增加SPS、PPS(在AUD后面),所以转换结果是AUD+PSlice+ISlice(IDR)。Mac是QuickTime播放器在解析PES时,不知道什么算法,会在第一种情形Crash,第二种情况丢失一个ISlice,出现图像失常。请注意,如果Mp4的帧格式符合常规,那么新老bento4生成的结果是一样的。
最后确认是老版本MP4Box的bug,它在生成的MP4文件时将I和P帧打在了一个Sample中。具体原因是这个版本的MP4Box是以0x00000001为起始码寻找NAL包,碰到以0x000001开头时(比如出问题的IDR帧)就会跳过去,而264标准中起始码0x000001或0x00000001都应支持的。
方案:更新Mp4Box
现象:播放有声音、无图像
范围:ipad、iphone,一个特定的频道
原因:在FLV文件转成TS文件时,FLV文件在没有同步帧上有SPS,PPS,转换逻辑据此判断H.264ES流中存在AUD(AccessUnitDelimiter),但是实际上不存在AUD,导致生成的TS文件中没有AUD,ios平台的播放器需要AUD,没有就不能播放视频。
方案:修正转换逻辑,直接判断有没有AUD,并补充AUD。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。