【发布时间】:2011-10-27 05:18:45
【问题描述】:
我正在尝试从 .mov 文件中解析 H.264 帧。我想我已经得出结论,来自 FFMPEG 的 AVFormat-part 的 mov.c 是要走的路。但是 mov.c 是未注释代码旁边的约 2600 行代码。我正在寻找使用 FFMPEG 的示例,尤其是解析任何文件类型的结构。不管是 MPEG4 还是 Quicktime Movie,因为它们的结构非常相似。
如果没有现有示例(我找不到任何示例),也许有人使用过它,可以给我几行代码,或者解释如何开始?
我正在尝试做的事情: 我使用 AVCaptureSession 从摄像机捕获样本,然后将这些样本编码为 H264 并在 AVAssetsWriter、AVAssetsWriterInput 和 AVAssetsWriterInputPixelBufferAdaptor 的帮助下写入文件。原因是我不能直接访问硬件 H264 编码,因为苹果不允许这样做。我现在需要做的(我认为不确定)是解析出来的:
.mov 文件中的“mdat”-atom(电影数据,我认为可能不止一个)。 然后是“vide”-atom,然后是vide-atom(视频数据样本,可能不止一个)。我认为会有几个我相信是框架的原子。这些将是“avc1”类型(这是 H264 的类型)。 请纠正我,因为我很确定我还没有正确理解所有这些。
然后我的问题是,我将如何解析单帧。我一直在阅读the documentation 并查看了iFrameExtractor(这不是很有帮助,因为它会解码帧)。当我应该使用 FFMPEG-AVFormat 中的mov.c 时,我想我已经正确理解了,但我不确定。
编辑: 我现在正在尝试这样:
我运行了 iFrameExtractor 的略微简化的初始化函数 iFrameExtractor,它在 .mov 文件中查找视频流。
-
我得到这样的框架数据:
AVPacket packet; av_read_frame(pFormatCtx, &packet); NSData *frame; if(packet.stream_index == videoStream){ frame = [NSData dataWithBytes:packet.data length:packet.size]; } videoStream++; av_free_packet(&packet); return frame;
然后我将它传递给 NSOperation 的一个子类,在该子类中保留它以等待上传。
但我收到 EXC_BAD_ACC,从帧复制数据时我做错了吗?有任何想法吗。当我尝试使用其(非原子,保留)属性设置类变量NSData* frame 时,我得到了 EXC_...。 (它在合成行上显示 EXC_BAD_ACC)
【问题讨论】:
-
mov.c 不会帮助您实现最终目标。如果您需要 MOV/MP4 解析帮助,它会很方便。另一个方便的库,用于当事情变得粗糙mp4v2。基本上你将不得不自己写这个。由于各种原因,没有图书馆会完成这项工作。
-
@Steve McFarlin,谢谢,除了 qt 文档以掌握 mov 文件的整个结构之外,您有任何阅读技巧,因为我真的很难掌握所有这些,对吗?原子甚至不需要按特定顺序排列?您认为哪一个最容易使用 mov 或 mp4?
-
问题 1 - 您需要阅读 ISO-14496-10 第 7.3 节和附录 B(14496-15 也很有帮助)。你需要知道什么是NALU。虽然可以使用 mp4v2 或 FFmpeg,但我不推荐它。我可以保证你将不得不修改这些库的源代码来做你想做的事。 MOV 文件是一个树形结构。解析非常容易。我建议你先写一个原子解析器。只需将每个原子的 FOURCC 代码转储到控制台即可。有一个简单的 Java 项目漂浮在某处,可以帮助您入门。
-
问题 2 - 实际上我还没有看到那个项目。它更可能是编码的 H264 帧。如果这是您要采用的路径,那么您应该使用movieFragmentInterval。这样,SPS/PPS NALU 在整部电影之前被写入文件。这些应该在额外数据字段中,并且很可能采用附件 B 格式。同样,使用 FFmpeg/mp4v2 会比从头开始编写更难。在 RT 中甚至可能无法使用这些库进行操作。您当然必须修改它们。
-
在 MOV 文件中,SPS/PPS NALU 位于 MOV 文件的标题中。在 MOV 文件完成之前,它们不会被写入。您可以在 iOS 中使用 movieFragmentInterval 创建一个“流式”快速时间文件,以便在任何示例数据之前写入此信息。但是,生成的文件对于“手动”解析要复杂得多。我不确定 FFmpeg 是否支持这种文件类型。 mdat 原子包含样本数据。如果您只存储 AVC 数据,那么这将是 I 和 P 帧(假设 Baseline 3.x)。再次。我强烈建议您从头开始编写。
标签: parsing ffmpeg video-processing quicktime mpeg-4