【问题标题】:Get PTS from raw H264 mdat generated by iOS AVAssetWriter从 iOS AVAssetWriter 生成的原始 H264 mdat 中获取 PTS
【发布时间】:2012-06-20 16:59:15
【问题描述】:

我正在尝试同时读取和写入由 AVAssetWriter 编写的 H.264 mov 文件。我设法提取了单个 NAL 单元,将它们打包到 ffmpeg 的 AVPackets 中,并使用 ffmpeg 将它们写入另一种视频格式。它工作正常,生成的文件播放良好,但播放速度不正确。如何从原始 H.264 数据计算正确的 PTS/DTS 值?或者也许还有其他方法可以得到它们?

这是我尝试过的:

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

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

  3. 将 PTS 设置为 0 或 AV_NOPTS_VALUE。没用。

通过谷歌搜索,我了解到原始 H.264 数据通常不包含任何时间信息。它有时可以在 SEI 中包含一些时间信息,但我使用的文件没有它。另一方面,有一些应用程序完全可以做我想做的事情,所以我想这是有可能的。

【问题讨论】:

  • 我也在尝试同时从 AVAssetWriter 写入的 mov 文件中读取 H.264,但无法使用管道/常规文件读取来完成。你是如何在写它的时候读到它的?谢谢!
  • 使用常规文件读取,而不是在 EOF 重新读取时停止。你的阅读操作迟早会成功。
  • @kolyuchiy - 调度源可以更好地利用系统。在 FILE 描述符上设置读取源。当有数据要读取时,将调用一个块。如果发生 EOF,只需清除 FILE 上的错误即可。

标签: ios ffmpeg avfoundation h.264 avassetwriter


【解决方案1】:

您要么必须自己生成它们,要么访问 MP4/MOV 容器中包含时间信息的 Atom 以生成 PTS/DTS 信息。 FFmpeg 在 libavformat 中的 mov.c 可能会有所帮助。

您使用 AVAssetWriter 编写的每个样本/帧都将与 VCL NAL 一对一映射。如果您所做的只是转换,那么让 FFmpeg 完成所有繁重的工作。从一种容器格式转换到另一种容器格式时,它将正确维护时间信息。

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

-- 编辑--

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

【讨论】:

  • 谢谢!实际上 CMSampleBuffers 确实包含映射到输出数据包的正确 PTS。我只是懒得一直朝那个方向走。这解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 2013-10-18
  • 2014-12-28
  • 2014-02-15
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 2022-06-18
  • 2021-10-20
相关资源
最近更新 更多