【发布时间】:2013-03-26 03:53:22
【问题描述】:
我注意到在 AVAssetWriterInput 的 iOS 文档中,您可以将 nil 传递给 outputSettings 字典以指定不应重新编码输入数据。
用于对附加到输出的媒体进行编码的设置。传递 nil 以指定不应重新编码附加的样本。
我想利用此功能传入原始 H.264 NAL 流,但我无法将原始字节流调整为 CMSampleBuffer,我可以将其传入 AVAssetWriterInput 的 appendSampleBuffer 方法。我的 NAL 流仅包含 SPS/PPS/IDR/P NAL(1、5、7、8)。我无法找到有关如何将预编码的 H264 数据与 AVAssetWriter 一起使用的文档或结论性答案。生成的视频文件无法播放。
如何将 NAL 单元正确打包到 CMSampleBuffers 中?我需要使用起始代码前缀吗?长度前缀?我是否需要确保每个CMSampleBuffer 只放一个 NAL?我的最终目标是使用 H264/AAC 创建 MP4 或 MOV 容器。
这是我一直在玩的代码:
-(void)addH264NAL:(NSData *)nal
{
dispatch_async(recordingQueue, ^{
//Adapting the raw NAL into a CMSampleBuffer
CMSampleBufferRef sampleBuffer = NULL;
CMBlockBufferRef blockBuffer = NULL;
CMFormatDescriptionRef formatDescription = NULL;
CMItemCount numberOfSampleTimeEntries = 1;
CMItemCount numberOfSamples = 1;
CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCMVideoCodecType_H264, 480, 360, nil, &formatDescription);
OSStatus result = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, [nal length], kCFAllocatorDefault, NULL, 0, [nal length], kCMBlockBufferAssureMemoryNowFlag, &blockBuffer);
if(result != noErr)
{
NSLog(@"Error creating CMBlockBuffer");
return;
}
result = CMBlockBufferReplaceDataBytes([nal bytes], blockBuffer, 0, [nal length]);
if(result != noErr)
{
NSLog(@"Error filling CMBlockBuffer");
return;
}
const size_t sampleSizes = [nal length];
CMSampleTimingInfo timing = { 0 };
result = CMSampleBufferCreate(kCFAllocatorDefault, blockBuffer, YES, NULL, NULL, formatDescription, numberOfSamples, numberOfSampleTimeEntries, &timing, 1, &sampleSizes, &sampleBuffer);
if(result != noErr)
{
NSLog(@"Error creating CMSampleBuffer");
}
[self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo];
});
}
请注意,我在writeSampleBuffer 方法内的样本缓冲区上调用CMSampleBufferSetOutputPresentationTimeStamp,我认为这是在我实际尝试附加它之前的有效时间。
感谢任何帮助。
【问题讨论】:
-
我的问题至少有一部分是我如何处理 CMSampleTimingInfo。我提到我正在使用
setOutputPresentationTimeStamp填写一个真实的时间戳。我现在意识到我还需要填写 CMSampleTimingInfo 的其他字段。我将decodeTimeStamp设置为kCMTimeInvalid,将duration设置为CMTimeMake(1, 30)。我现在得到一个总时间合适的可搜索视频容器,但没有视频(在 VLC 中测试)。
标签: iphone ios h.264 avassetwriter cmsamplebufferref