我正在编写一个transmuxer,将MPEG-TS文件从HLS流转换为MP4文件,然后可以在网络浏览器中播放。
我原本希望能够将TS文件简单地一对一映射到MP4文件,但事实证明,某些HLS流被分割,使得各个TS文件并不总是在IDR上启动帧;每当您穿过分段边界时,这会导致冻结图像和口吃。
我想我可以通过连接来自多个TS文件的数据,忽略原始文件边界,自己识别视频流中的IDR帧,以及在IDR帧上启动每个新的MP4段来解决这个问题。但是,如果我这样做,我担心文件的结束可能存在损坏; IDR帧保证以后的帧不能引用任何先前的数据,但没有任何内容表明早期的B帧不能向前看IDR帧。
那么,我怎么知道切割的安全位置,这样切割前的B帧不会试图超越它?
答案 0 :(得分:5)
如果您在IDR框架处结束切割,我认为您没有任何问题。但我不是百分百肯定。
来自H.264规范,例如RFC3984:
IDR图片:仅包含I或SI切片的编码图片 切片类型导致"重置"在解码过程中。后 IDR图像的解码,所有后面的编码图像 可以解码解码顺序而无需任何帧间预测 在IDR图片之前解码的图片。
请注意,在解码顺序中,帧不能引用IDR之前的其他帧。
为了使B帧在IDR帧之后引用任何帧,引用的帧必须出现在文件的前面,因为它必须首先被解码。这样B帧必须在IDR帧之后。这意味着该B帧不能在IDR帧之前引用任何帧。在我看来,这没有任何意义。
例如:假设按显示顺序显示以下帧:
(other frames) B IDR P
如果P引用IDR,而B引用P,则必须是解码顺序:
(other frames) IDR P B
在这个例子中,B不能引用任何其他帧,它只能引用IDR和P.
请注意,即使发生这种情况,如果您在IDR之后找到IDR之后的帧,也可以检测到这一点。