gpt4 book ai didi

iphone - 将 AVAssetWriter 与原始 NAL 单元一起使用

转载 作者:可可西里 更新时间:2023-11-01 03:17:49 24 4
gpt4 key购买 nike

我在 iOS 文档中注意到 AVAssetWriterInput你可以通过nil对于 outputSettings字典来指定不应重新编码输入数据。

The settings used for encoding the media appended to the output. Pass nil to specify that appended samples should not be re-encoded.

我想利用此功能传入原始 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];
});
}

请注意,我正在调用 CMSampleBufferSetOutputPresentationTimeStampwriteSampleBuffer 内的样本缓冲区上在我实际尝试追加它之前,我认为它是有效时间的方法。

感谢任何帮助。

最佳答案

我设法在 VLC 而非 QuickTime 中播放视频。我使用与我在上面发布的代码类似的代码将 H.264 NAL 导入 CMSampleBuffers。

我有两个主要问题:

  1. 我没有正确设置 CMSampleTimingInfo(如我上面的评论所述)。
  2. 我没有正确打包原始 NAL 数据(不确定记录在何处,如果有的话)。

为了解决 #1,我设置了 timing.duration = CMTimeMake(1, fps);,其中 fps 是预期的帧速率。然后我设置 timing.decodeTimeStamp = kCMTimeInvalid; 意味着样本将按解码顺序给出。最后,我通过计算绝对时间来设置 timing.presentationTimeStamp,我也将其与 startSessionAtSourceTime 一起使用。

为了解决 #2,通过反复试验,我发现以下列形式提供我的 NAL 单元是有效的:

[7 8 5] [1] [1] [1]..... [7 8 5] [1] [1] [1]..... (repeating)

其中每个 NAL 单元都以等于 0x00000001 的 32 位起始代码为前缀。

可能出于同样的原因,它不能在 QuickTime 中播放,我仍然无法将生成的 .mov 文件移动到相册(ALAssetLibrary 方法 videoAtPathIsCompatibleWithSavedPhotosAlbum 是未能说明“无法播放电影”。希望知道发生了什么的人可以发表评论。谢谢!

关于iphone - 将 AVAssetWriter 与原始 NAL 单元一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15629117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com