Ios 用于写入H.264 AVCC流的CMSampleBufferRef池
我正在使用AVAssetWriter/AVAssetWriterInput将H.264原始数据写入MP4文件。当我从远程服务器接收数据时,我使用以下CoreMedia API获取一个样本缓冲区(CMSampleBufferRef),该缓冲区包含AVCC格式的H.264数据,然后通过向Ios 用于写入H.264 AVCC流的CMSampleBufferRef池,ios,objective-c,video,avfoundation,h.264,Ios,Objective C,Video,Avfoundation,H.264,我正在使用AVAssetWriter/AVAssetWriterInput将H.264原始数据写入MP4文件。当我从远程服务器接收数据时,我使用以下CoreMedia API获取一个样本缓冲区(CMSampleBufferRef),该缓冲区包含AVCC格式的H.264数据,然后通过向AVAssetWriterInput发送消息(BOOL)appendSampleBuffer:(CMSampleBufferRef)sampleBuffer,将其追加到MP4文件中: CMBlockBufferCre
AVAssetWriterInput
发送消息(BOOL)appendSampleBuffer:(CMSampleBufferRef)sampleBuffer
,将其追加到MP4文件中:
CMBlockBufferCreateWithMemoryBlock
创建内存块CMBlockBufferReplaceDataBytes
将AVCC格式的H.264写入内存块CMSampleBufferCreate
使用内存块和包含H.264“extradata”的格式描述符创建样本缓冲区CMSampleBufferRef
和CMBlockBufferRef
基本上,我希望拥有一个CMSampleBuffer
池,并能够在从远程服务器接收新的H.264数据时更新其内存内容和格式描述符
我知道存在允许访问CVPixelBufferPool
的avassetwriterinportpixelbufferadapter
,但我不能在我的例子中使用它,因为据我所知,要正确实例化像素缓冲适配器,至少我需要能够传递视频帧维度,直到解析流为止。此外,我不知道如何使用CVPixelBuffer
编写H.264“extradata”。因此,我认为我需要坚持使用CMSampleBuffer
。不幸的是,CoreMedia API似乎无法在创建样本缓冲区后更新内存块或格式描述符(据我所知,我只能访问这些对象的不可变引用)。因此,到目前为止,我能做的最好的事情就是重用内存块CMBlockBufferRef
,但我仍在重新创建示例缓冲区。我的代码如下。希望这里的人能对如何实现CMSampleBuffer
池有一些想法,或者也许是一种更有效的方法,将H.264 AVCC流写入MP4
- (CMSampleBufferRef)sampleBufferWithData:(NSData*)data formatDescriptor:(CMFormatDescriptionRef)formatDescription
{
OSStatus result;
CMSampleBufferRef sampleBuffer = NULL;
// _blockBuffer is a CMBlockBufferRef instance variable
if (!_blockBuffer)
{
size_t blockLength = MAX_LENGTH;
result = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
NULL,
blockLength,
kCFAllocatorDefault,
NULL,
0,
blockLength,
kCMBlockBufferAssureMemoryNowFlag,
&_blockBuffer);
// check error
}
result = CMBlockBufferReplaceDataBytes([data bytes], _blockBuffer, 0, [data length]);
// check error
const size_t sampleSizes = [data length];
CMSampleTimingInfo timing = [self sampleTimingInfo];
result = CMSampleBufferCreate(kCFAllocatorDefault,
_blockBuffer,
YES,
NULL,
NULL,
formatDescription,
1,
1,
&timing,
1,
&sampleSizes,
&sampleBuffer);
// check error
return sampleBuffer;
}
如果您正在接收原始H.264数据,那么就不需要做很多工作,也根本不需要处理CoreMedia 缓冲所有VCL NAL单元,直到获得SPS/PPS NAL单元。从它们创建外部数据,然后将所有缓冲和新的VCL NAL单元附加到文件中。如果收到附件B格式的NAL单位,则需要将其转换为AVCC格式(基本上用长度代码替换起始代码) 如果要解码未压缩图片或要解码压缩图片,只需使用“CMSampleBuffer”。由于您已经在处理原始H.264流,并且只想将其写入MP4文件,所以只需这样做。这里根本不需要接触CoreMedia 关于CoreMedia:您将视频信息包装在
CMBlockBuffer
中。此缓冲区与CMVideoFormatDescriptor
(从SPS/PPS生成)加上CMTime
组成CMSampleBuffer
。多个CMSampleBuffers
组成一个“CMSampleBufferPool”
不涉及“CVPixelBuffer”和“CVPixelBufferPool”。在处理编码/解码h.264视频时,这些是“VTCompressionSession”或“VTDecompressionSession”的输入或输出
正如在您的案例中所说的,根本不需要接触任何核心framworks,因为您只是在创建一个文件
有关附录B和AVCC流格式的概述可在此处找到: