AVFoundation 的 AVAssetWriterInput 期望MediaDataInRealTime 属性究竟是做啥的?

Posted

技术标签:

【中文标题】AVFoundation 的 AVAssetWriterInput 期望MediaDataInRealTime 属性究竟是做啥的?【英文标题】:What exactly does AVFoundation's AVAssetWriterInput expectsMediaDataInRealTime property do?AVFoundation 的 AVAssetWriterInput 期望MediaDataInRealTime 属性究竟是做什么的? 【发布时间】:2012-10-11 10:29:37 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

【参考方案2】:

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

expectsMediaDataInRealTime 表示帧被推送到AVAssetWriter - 无论它们是从相机还是从文件推送 30FPS...这只是意味着 AVAssetWriter 是在帧到来时处理帧。

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

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

【讨论】:

以上是关于AVFoundation 的 AVAssetWriterInput 期望MediaDataInRealTime 属性究竟是做啥的?的主要内容,如果未能解决你的问题,请参考以下文章

AVFoundation下的视频分帧处理

AVFoundation 初识

AVFoundation自己定义音视频频播放

视频格式、AVFoundation 和 UTI

Mac OS X 上的 AVFoundation + GC

IOS开发中AVFoundation中AVAudioPlayer的使用