从iOS AVAssetWriter生成的原始H264 mdat获取PTS

我试图同时读写由AVAssetWriter写的H.264 mov文件。 我设法提取单独的NAL单元,将它们打包到ffmpeg的AVPackets中,并使用ffmpeg将它们写入另一个video格式。 它的工作原理和结果文件播放良好,除了播放速度不正确。 如何从原始H.264数据计算正确的PTS / DTS值? 或者,也许还有其他的方式来得到它们?

以下是我所尝试的:

  1. 将捕获的最小/最大帧速率限制为30,并假定输出文件将为30 fps。 实际上它的fps总是比我设定的值小。 而且,我认为fps在数据包之间并不是一成不变的。

  2. 记住每个书面样本的呈现时间戳,并假定样本与NALU一一映射,并将保存的时间戳应用于输出数据包。 这不起作用。

  3. 将PTS设置为0或AV_NOPTS_VALUE。 不起作用。

从谷歌search我了解,原始的H.264数据通常不包含任何时间信息。 它有时可以在SEI内部有一些时间信息,但我使用的文件没有它。 另一方面,有一些应用程序正在做我正在做的事情,所以我认为这是可能的。

您将不得不自己生成它们,或访问MP4 / MOV容器中包含Atom的定时信息来生成PTS / DTS信息。 在libavformat中FFmpeg的mov.c可能会有所帮助。

使用AVAssetWriter编写的每个样本/框架将与VCL NAL一一对应。 如果你正在做的是转换,然后FFmpeg做所有的繁重工作。 当从一个容器格式转到另一个容器格式时,它将适当地保持时间信息。

由AVAssetWriter生成的比特stream不包含SEI数据。 它只包含SPS / PPS / I / P帧。 SPS也不包含VUI或HRD参数。

– 编辑 –

另外,请记住,如果您要保存CMSampleBufferRef的PTS信息,那么时基可能与目标容器的时基不同。 例如,AVFoundation时间基准是纳秒,FLV文件是毫秒。