截断 H.264 数据的安全位置?

Safe place to truncate H.264 data?

我正在编写一个 transmuxer,将 MPEG-TS 文件从 HLS 流转换为 MP4 文件,然后可以在网络浏览器中播放。

我原本希望能够将 TS 文件与 MP4 文件进行简单的一对一映射,但事实证明,一些 HLS 流被分割了,因此各个 TS 文件并不总是开始在 IDR 帧上;这会导致图像冻结并在您越过片段边界时卡顿。

我想我可以通过连接来自多个 TS 文件的数据,忽略原始文件边界,自己识别视频流中的 IDR 帧,并在 IDR 帧上开始每个新的 MP4 片段来解决这个问题。但是,如果我这样做,我担心文件的 结尾 可能会损坏; IDR 帧保证后面的帧不能引用任何前面的数据,但没有任何迹象表明前面的 B 帧不能向前看过去的 IDR 帧。

那么,我如何知道在哪里进行剪切是安全的,以便剪切前的 B 帧不会试图越过它?

我认为如果您在 IDR 帧处结束剪辑,您不会有任何问题。但我不是 100% 确定。

来自 H.264 规范,例如 RFC3984:

IDR picture: A coded picture containing only slices with I or SI slice types that causes a "reset" in the decoding process. After the decoding of an IDR picture, all following coded pictures in decoding order can be decoded without inter prediction from any picture decoded prior to the IDR picture.

请注意,在解码顺序中,帧不能引用 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 之前的帧,也可以检测到这一点。