gpt4 book ai didi

ios - CMSampleBufferRef 的深拷贝

转载 作者:可可西里 更新时间:2023-11-01 06:03:56 26 4
gpt4 key购买 nike

我正在尝试为音频和视频连接执行 CMSampleBufferRef 的深度复制?我需要使用此缓冲区进行延迟处理。有人可以在这里帮助指向示例代码。

谢谢

最佳答案

我解决了这个问题

我需要长期访问示例数据。

尝试多种方式:

CVPixelBufferRetain -----> 程序坏了CVPixelBufferPool -----> 程序坏了CVPixelBufferCreateWithBytes ---->可以解决这个程序,但是会降低性能,不建议苹果这样做

CMSampleBufferCreateCopy --->可以,苹果推荐

列表:为了保持最佳性能,一些样本缓冲区直接引用可能需要由设备系统和其他捕获输入重用的内存池。对于尽可能少地复制内存块的未压缩设备 native 捕获,情况经常如此。如果多个样本缓冲区引用此类内存池的时间过长,输入将无法再将新样本复制到内存中,这些样本将被丢弃。如果您的应用程序通过将提供的 CMSampleBuffer 对象保留太久而导致样本被丢弃,但它需要长时间访问样本数据,请考虑将数据复制到新缓冲区,然后在样本缓冲区上调用 CFRelease (如果它之前被保留)以便它引用的内存可以被重用。

编号:https://developer.apple.com/reference/avfoundation/avcapturefileoutputdelegate/1390096-captureoutput

这可能是你需要的:

编译指示标记-captureOutput

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
if (connection == m_videoConnection) {
/* if you did not read m_sampleBuffer ,here you must CFRelease m_sampleBuffer, it is causing samples to be dropped
*/
if (m_sampleBuffer) {
CFRelease(m_sampleBuffer);
m_sampleBuffer = nil;
}

OSStatus status = CMSampleBufferCreateCopy(kCFAllocatorDefault, sampleBuffer, &m_sampleBuffer);
if (noErr != status) {
m_sampleBuffer = nil;
}
NSLog(@"m_sampleBuffer = %p sampleBuffer= %p",m_sampleBuffer,sampleBuffer);
}
}

pragma mark -get CVPixelBufferRef 长期使用

- (ACResult) readVideoFrame: (CVPixelBufferRef *)pixelBuffer{
while (1) {
dispatch_sync(m_readVideoData, ^{
if (!m_sampleBuffer) {
_readDataSuccess = NO;
return;
}

CMSampleBufferRef sampleBufferCopy = nil;
OSStatus status = CMSampleBufferCreateCopy(kCFAllocatorDefault, m_sampleBuffer, &sampleBufferCopy);
if ( noErr == status)
{
CVPixelBufferRef buffer = CMSampleBufferGetImageBuffer(sampleBufferCopy);

*pixelBuffer = buffer;

_readDataSuccess = YES;

NSLog(@"m_sampleBuffer = %p ",m_sampleBuffer);

CFRelease(m_sampleBuffer);
m_sampleBuffer = nil;

}
else{
_readDataSuccess = NO;
CFRelease(m_sampleBuffer);
m_sampleBuffer = nil;
}
});

if (_readDataSuccess) {
_readDataSuccess = NO;
return ACResultNoErr;
}
else{
usleep(15*1000);
continue;
}
}
}

然后你可以这样使用它:

-(void)getCaptureVideoDataToEncode{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(){
while (1) {
CVPixelBufferRef buffer = NULL;
ACResult result= [videoCapture readVideoFrame:&buffer];
if (ACResultNoErr == result) {
ACResult error = [videoEncode encoder:buffer outputPacket:&streamPacket];
if (buffer) {
CVPixelBufferRelease(buffer);
buffer = NULL;
}
if (ACResultNoErr == error) {
NSLog(@"encode success");
}
}
}
});
}

关于ios - CMSampleBufferRef 的深拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34972377/

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