bsi*_*ang 8 iphone h.264 ios avassetwriter cmsamplebufferref
我iOS的文档中发现了AVAssetWriterInput可以传递nil的outputSettings字典来指定输入数据不应该被重新编码.
用于编码附加到输出的媒体的设置.传递nil以指定不应重新编码附加的样本.
我想利用这个功能传递原始H.264 NAL流,但是我无法将原始字节流调整为CMSampleBuffer可以传递到AVAssetWriterInput的appendSampleBuffer方法.我的NAL流只包含SPS/PPS/IDR/P NAL(1,5,7,8).我无法找到有关如何使用AVAssetWriter预编码H264数据的文档或结论性答案.生成的视频文件无法播放.
如何正确打包NAL单元CMSampleBuffers?我需要使用开始代码前缀吗?长度前缀?我需要确保每个只放一个NAL CMSampleBuffer吗?我的最终目标是使用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];
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,在我实际尝试追加它之前,我正在调用方法CMSampleBufferSetOutputPresentationTimeStamp内部的示例缓冲区,writeSampleBuffer我认为这是一个有效的时间.
任何帮助表示赞赏.
我设法在 VLC 中播放视频,但在 QuickTime 中却不行。我使用与上面发布的代码类似的代码将 H.264 NAL 放入 CMSampleBuffers 中。
我有两个主要问题:
为了解决#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)
Run Code Online (Sandbox Code Playgroud)
其中每个 NAL 单元都以等于 的 32 位起始码作为前缀0x00000001。
大概出于同样的原因,它没有在 QuickTime 中播放,我仍然无法将生成的 .mov 文件移动到相册(该ALAssetLibrary方法videoAtPathIsCompatibleWithSavedPhotosAlbum失败,提示“电影无法播放。”希望有人知道是什么继续可以评论。谢谢!
| 归档时间: |
|
| 查看次数: |
2671 次 |
| 最近记录: |