9

我正在开发一个应用程序,它从磁盘读取媒体数据,将其转换为适当的像素格式,然后将其传递给 AVAssetWriter 进行压缩并写入磁盘。我正在自己阅读交错而不使用 AVAssetReader。我的读者确保以串行方式呈现恰好一帧的视频数据和一帧的音频数据。我遇到的问题是,如果我没有将 expectsMediaDataInRealTime 属性设置为YES,视频资产编写器将始终返回NO对于 isReadyForMoreMediaData 恰好在 30 帧之后。如果我在 30 帧之前停止写入,它工作正常并且输出文件有效。但是,如果我将 expectsMediaDataInRealTime 设置为 YES,它会在整个持续时间(可能是几千帧)内完美运行。在将 expectsMediaDataInRealTime 设置为 YES 开始转码操作后,我观察了应用程序在压缩很长视频的过程中的内存使用情况,没有任何不合理的内存使用或任何内存泄漏。生成的 MOV 文件看起来确实写得很正常,例如,正如人们所期望的那样,音频数据与视频数据交织在一起。

那么,如果将 expectsMediaDataInRealTime 设置为 YES 没有明显的缺点,我为什么还要将其设置为 NO 呢?这仅在使用 Apple API 读取数据(使用 AVAssetReader)时适用吗?文档说此属性控制写入“以理想的交错模式写入媒体数据,以提高存储和播放效率”,但是当 expectsMediaDataInRealTime 设置为 YES 时,isReadyForMoreMediaData 永远不会返回 NO,并且文件似乎被完美写入。那么,如果 AVAssetWriter 在此属性设置为 YES 时可以执行此操作,为什么设置为 NO 时不能执行此操作?来源完全一样。

除了“确保正确计算 readyForMoreMediaData 的值”(这对我来说绝对没有任何意义)之外,这个属性究竟做了什么?

4

2 回答 2

0

据我了解,将 expectsMediaDataInRealTime 设置为 YES 意味着编码器期待实时数据流馈送,例如摄像头等。在这种情况下,您将不断向编码器馈送数据,isReadyForMoreMediaData 会告诉您是否可以馈送数据到编码器。如果 isReadyForMoreMediaData 为 NO,您将不得不删除当前样本,并等待下一个样本到达并再次检查 isReadyForMoreMediaData 是否为 YES。

另一方面,如果 expectsMediaDataInRealTime 为 NO,则表示编码器不是实时源,而是离线数据流,例如 AVAssetReader。在这种情况下,因为你可以自己控制流的速度,所以,当 isReadyForMoreMediaData 为 NO 时,你可以保持输入和编码器,等待 isReadyForMoreMediaData 变为 YES(例如,使用无限循环休眠并等待 isReadyForMoreMediaData变化等)。

我假设这样做的目的是为了内部机制尝试尽可能对齐交错音频和视频时间戳,因此,播放器和解码器不会预先获取大量数据以进行播放。这是数据源端数据完整性和播放端体验之间的折衷。虽然,我想你可以一直使用 expectsMediaDataInRealTime 为 YES,但最好丢弃早期输入的样本,以防 isReadyForMoreMediaData==NO。

于 2016-03-15T13:09:59.403 回答
0

据我了解,这不是完美的命名,而且有点令人困惑。

expectsMediaDataInRealTime意味着帧被推送到AVAssetWriter- 无论它们是从相机还是从文件推送 30FPS 都没有关系......它只是意味着AVAssetWriter当它到来时处理帧。

如果它设置为false,那么你应该拉框架,从源头索取它们。所以它与 无关realTime,它是定义AVAssetWriter是在准备好时拉框架,还是在框架可用时强制准备好并处理它。

此标志定义谁控制帧到达的时间AVAssetWriter

于 2018-08-29T11:17:54.367 回答