AVAssetWriter输入H.264直通至QuickTime(.mov)

我有一个由类型1(P帧),5(I帧),7(SPS)和8(PPS)组成的H.264 / AVC NAL流。 我想将它们写入.mov文件而不用重新编码。 我试图使用AVAssetWriter来做到这一点。 AVAssetWriterInput的文档声明:

对outputSettings传递nil指示输入通过附加采样,在写入输出文件之前不做任何处理。 例如,如果你正在追加已经处于理想压缩格式的缓冲区,这很有用。 但是,只有在写入QuickTime影片文件时才支持直通(即,AVAssetWriter已使用AVFileTypeQuickTimeMovie进行初始化)。 对于其他文件类型,您必须指定非零输出设置。

我试图从这些NAL中创建CMSampleBuffers并将它们追加到资产编写器输入中,但我无法以产生格式良好的.mov文件的方式输入数据,并且我无法在任何地方找到任何线索如何做到这一点。

到目前为止,我得到的最好结果是以附件B字节流格式(以7 8 5 1 1 1 ....重复的顺序)传递NAL,并在VLC中播放结果。 因此,我知道NAL包含有效数据,但由于.mov文件没有avcC原子,并且mdat原子填充了附件B字节流,因此QuickTime不会播放视频。

现在我试图用4字节(由lengthSizeMinusOne字段指定)长度字段而不是附件B分隔符lengthSizeMinusOne ,这就是它们应该如何被包装到mdat原子中,直到我知道。

我对如何让资产编写者编写avcC原子感到不知所措。 我追加的每个样本都会被推入mdat原子中。

有谁知道我可以如何将原始的H.264数据传递到配置为pass through(nil outputSettings)的AVAssetWriterInput并让它生成一个正确形成的QuickTime文件?


我已经提交了苹果的TSI,并找到了答案。 我希望这能在未来节省一些时间。

CMSampleBuffers与它们关联了一个CMFormatDescription,它包含样本缓冲区中数据的描述。

用于创建格式描述的函数原型如下所示:

OSStatus CMVideoFormatDescriptionCreate (
  CFAllocatorRef allocator,
  CMVideoCodecType codecType,
  int32_t width,
  int32_t height,
  CFDictionaryRef extensions,
  CMVideoFormatDescriptionRef *outDesc
);

我从Apple技术人员那里了解到,我可以使用扩展参数传递包含avcC原子数据的字典。

扩展词典应该具有以下形式:

[kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms ---> ["avcC" ---> <avcC Data>]]

[]代表词典。 这个字典可能被用来传递除avcC以外的任意原子的数据。

以下是我用来创建extensions字典的代码,我将其传入CMVideoFormatDescriptionCreate

    const char *avcC = "avcC";
    const CFStringRef avcCKey = CFStringCreateWithCString(kCFAllocatorDefault, avcC, kCFStringEncodingUTF8);
    const CFDataRef avcCValue = CFDataCreate(kCFAllocatorDefault, [_avccData bytes], [_avccData length]);
    const void *atomDictKeys[] = { avcCKey };
    const void *atomDictValues[] = { avcCValue };
    CFDictionaryRef atomsDict = CFDictionaryCreate(kCFAllocatorDefault, atomDictKeys, atomDictValues, 1, nil, nil);

    const void *extensionDictKeys[] = { kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms };
    const void *extensionDictValues[] = { atomsDict };
    CFDictionaryRef extensionDict = CFDictionaryCreate(kCFAllocatorDefault, extensionDictKeys, extensionDictValues, 1, nil, nil);
链接地址: http://www.djcxy.com/p/72037.html

上一篇: AVAssetWriterInput H.264 Passthrough to QuickTime (.mov)

下一篇: EPPlus with OpenXML and streams