1.需求
在解码带B帧的视频编码码流中,由于B帧的存在,导致parse出来的数据时间戳本身不是连续的,因为B帧需要可能需要参考后面的帧.因此,解码完成后需要对码流解码做一个重排序
2.实现原理
首先分析parse出来的数据的时间戳,后面得出的结论是除了第一帧时间戳为0,总体时间戳是增长的,后面每4帧为一组,每组中的顺序需要重新排序,排序后即可实现时间戳连续递增.
考虑内存开销,我们每次缓存4帧视频数据,将其放入线性表中,然后使用排序算法对这4帧数据根据pts做一个排序,排好序后即可传给渲染模块将其渲染到屏幕上.
注意: 使用FFmpeg硬解无需关心排序问题,因为FFmpeg内部有缓存排序机制,即从FFmepg拿到解码后的数据可直接渲染。
3.TODO
因为我们无法判断码流中的B帧是否依赖后面的视频帧,而是 经过分析可得视频帧的时间戳是总体增长,每组4帧,需要对4帧数据进行排序,目前暂时未知是否有非4帧一组的视频帧,如果有则此Demo会有问题,因此如果有了解此方面大神望评论告知更好的解决方案.
4.总体架构
本文基于已实现解码一个包含带B帧的H.265码流文件.因此,这里不对parse,解码,渲染做过多说明,如需了解参考阅读前提中的链接.
下面是从FFmpeg parse H.265文件得到的时间戳,我们可以看到,parse出来的时间戳总体是递增的,除了第一帧时间戳为0的数据外,剩下的时间戳均以4个一组,每组内时间戳不是递增的,因为解码时我们仍需按照Parse出来的数据送去解码,所以,我们只能对解码后的数据做一个排序,即将每组数据装入一个线性表,然后使用任一一种排序算法对其排序。
+0800 XDXVideoDecoder[1489:223381] Test - 0.000000
2019-06-25 12:38:09.656282+0800 XDXVideoDecoder[1489:223381] Test - 0.133333
2019-06-25 12:38:09.659350+0800 XDXVideoDecoder[1489:223381] Test - 0.066667
2019-06-25 12:38:09.660900+0800 XDXVideoDecoder[1489:223381] Test - 0.033333
2019-06-25 12:38:09.662889+0800 XDXVideoDecoder[1489:223381] Test - 0.100000
2019-06-25 12:38:09.664786+0800 XDXVideoDecoder[1489:223381] Test - 0.266667
2019-06-25 12:38:09.666900+0800 XDXVideoDecoder[1489:223381] Test - 0.200000
2019-06-25 12:38:09.668196+0800 XDXVideoDecoder[1489:223381] Test - 0.166667
2019-06-25 12: