CMSampleBufferGetImageBuffer 中的内存泄漏

2023-12-12

我得到了一个UIImage from a CMSampleBufferRef每 N 个视频帧进行视频缓冲,例如:

- (void)imageFromVideoBuffer:(void(^)(UIImage* image))completion {
    CMSampleBufferRef sampleBuffer = _myLastSampleBuffer;
    if (sampleBuffer != nil) {
        CFRetain(sampleBuffer);
        CIImage *ciImage = [CIImage imageWithCVPixelBuffer:CMSampleBufferGetImageBuffer(sampleBuffer)];
        _lastAppendedVideoBuffer.sampleBuffer = nil;
        if (_context == nil) {
            _context = [CIContext contextWithOptions:nil];
        }
        CVPixelBufferRef buffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        CGImageRef cgImage = [_context createCGImage:ciImage fromRect:
                              CGRectMake(0, 0, CVPixelBufferGetWidth(buffer), CVPixelBufferGetHeight(buffer))];
        __block UIImage *image = [UIImage imageWithCGImage:cgImage];

        CGImageRelease(cgImage);
        CFRelease(sampleBuffer);

        if(completion) completion(image);

        return;
    }
    if(completion) completion(nil);
}

XCode 和 Instruments 检测到内存泄漏,但我无法消除它。 我像往常一样发布 CGImageRef 和 CMSampleBufferRef:

CGImageRelease(cgImage);
CFRelease(sampleBuffer);

[UPDATE]我把AVCapture输出回调以获取sampleBuffer.

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    if (captureOutput == _videoOutput) {
        _lastVideoBuffer.sampleBuffer = sampleBuffer;
        id<CIImageRenderer> imageRenderer = _CIImageRenderer;

        dispatch_async(dispatch_get_main_queue(), ^{
            @autoreleasepool {
                CIImage *ciImage = nil;
                ciImage = [CIImage imageWithCVPixelBuffer:CMSampleBufferGetImageBuffer(sampleBuffer)];
                if(_context==nil) {
                    _context = [CIContext contextWithOptions:nil];
                }
                CGImageRef processedCGImage = [_context createCGImage:ciImage
                                                             fromRect:[ciImage extent]];
                //UIImage *image=[UIImage imageWithCGImage:processedCGImage];
                CGImageRelease(processedCGImage);
                NSLog(@"Captured image %@", ciImage);
            }
        });

泄漏的代码是createCGImage:ciImage:

CGImageRef processedCGImage = [_context createCGImage:ciImage
                                                             fromRect:[ciImage extent]];

甚至有一个autoreleasepool, the CGImageRelease of the CGImage参考和一个CIContext作为实例属性。

这似乎是这里解决的同一问题:无法在 iOS 上将 CIImage 保存到文件而不发生内存泄漏

[更新] 泄漏似乎是由于错误造成的。该问题在中得到了很好的描述iOS 9 上 CIContext createCGImage 内存泄漏?

示例项目展示了如何重现此泄漏:http://www.osamu.co.jp/DataArea/VideoCameraTest.zip

最后的评论保证

看起来他们在 9.1b3 中修复了这个问题。如果有人需要解决方法 在 iOS 9.0.x 上工作,我能够让它工作:

在测试代​​码中(在本例中为 Swift):

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)  
    {  
        if (error) return;  

        __block NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"ipdf_pic_%i.jpeg",(int)[NSDate date].timeIntervalSince1970]];  

        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];  
        dispatch_async(dispatch_get_main_queue(), ^  
        {  

            @autoreleasepool  
            {  
                CIImage *enhancedImage = [CIImage imageWithData:imageData];  

                if (!enhancedImage) return;  

                static CIContext *ctx = nil; if (!ctx) ctx = [CIContext contextWithOptions:nil];  

                CGImageRef imageRef = [ctx createCGImage:enhancedImage fromRect:enhancedImage.extent format:kCIFormatBGRA8 colorSpace:nil];  

                UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationRight];  

                [[NSFileManager defaultManager] createFileAtPath:filePath contents:UIImageJPEGRepresentation(image, 0.8) attributes:nil];  

                CGImageRelease(imageRef);  
            }  
        });  
    }]; 

iOS9.0 的解决方法应该是

extension CIContext {  
    func createCGImage_(image:CIImage, fromRect:CGRect) -> CGImage {  
        let width = Int(fromRect.width)  
        let height = Int(fromRect.height)  

        let rawData =  UnsafeMutablePointer<UInt8>.alloc(width * height * 4)  
        render(image, toBitmap: rawData, rowBytes: width * 4, bounds: fromRect, format: kCIFormatRGBA8, colorSpace: CGColorSpaceCreateDeviceRGB())  
        let dataProvider = CGDataProviderCreateWithData(nil, rawData, height * width * 4) {info, data, size in UnsafeMutablePointer<UInt8>(data).dealloc(size)}  
        return CGImageCreate(width, height, 8, 32, width * 4, CGColorSpaceCreateDeviceRGB(), CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue), dataProvider, nil, false, .RenderingIntentDefault)!  
    }  
}  

我们在创建的应用程序中遇到了类似的问题,我们使用 OpenCV 处理每个帧的特征关键点,并每隔几秒发送一帧。运行一段时间后,我们最终会收到相当多的内存压力消息。

我们设法通过在它自己的自动释放池中运行我们的处理代码来纠正这个问题,如下所示(jpegDataFromSampleBufferAndCrop 执行与您正在执行的操作类似的操作,但添加了裁剪):

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
        @autoreleasepool {

            if ([self.lastFrameSentAt timeIntervalSinceNow] < -kContinuousRateInSeconds) {

                NSData *imageData = [self jpegDataFromSampleBufferAndCrop:sampleBuffer];

                if (imageData) {
                    [self processImageData:imageData];
                }

                self.lastFrameSentAt = [NSDate date];

                imageData = nil;
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMSampleBufferGetImageBuffer 中的内存泄漏 的相关文章

  • 自动布局:3.5 英寸和 4 英寸屏幕的布局一致性与比例元素间距

    我想使用 AutoLayout 来定位控件 使其之间的垂直间距成比例 避免在 3 5 英寸屏幕上进行裁剪 避免在 4 英寸屏幕上出现空白底部空间 正如其他答案中所建议的 我可以使用具有 等高 约束的间隔视图 并在必要时更改乘数 然而 最终的
  • 错误:“无效数据消息 - 全部长度必须为:8” - PickerIOS

    Edit 似乎如果我注释掉第 63 行 this setState logged in true 行 我就不会收到错误 我的猜测是 我尝试根据用户是否登录来更改渲染函数中显示的内容的方式是导致此错误的原因 有任何想法吗 我感觉 在理解 Re
  • 在 iPhone 中创建类似 facebook 菜单导航的视图 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我需要在我的 iPhone 应用程序中创建如下所示的视图 我不知道该怎么做 视图描述 如果我按下视图中箭头指示的按钮图标 则会出现一个新视
  • 从 Social.framework(iOS6) 获取 Facebook 访问令牌

    我需要检索我在 设置 应用程序中设置的系统帐户的 Facebook 访问令牌 我知道 Social framework iOS6 知道我所有的 FB 帐户信息 并且我可以使用 SLRequest 类对 Graph API 执行 API 调用
  • 在 iOS 7 中创建 UUID 和 UDID

    我想创建 UUID 我下面有可以创建 UUID 的代码 如何在 iOS7 中创建具有多个供应商相同 ID 的 UDID NSString stringWithNewUUID CFUUIDRef uuidObj CFUUIDCreate ni
  • 在 NSData 和 base64 字符串之间转换

    在之间进行转换的最简单和最快的代码是什么NSData和一个base64字符串 我读过很多解决方案 其中大部分涉及添加另一个类等 我找到了一个很好的解决方案here http cocoawithlove com 2009 06 base64
  • iOS、Swift 3 - 当我从详细视图返回后单击“取消”时,UISearchBar 消失

    我在containerView中有一个tableView 以编程方式向其添加一个搜索栏 一切工作正常 除了这种情况 当我点击一个单元格时 当 tableView 由 searchBar 过滤时 然后我从明细视图返回 通过推送转场呈现 然后我
  • 签署 apple-app-site-association

    我尝试实施iOS9 Universal Links 我正在使用这个教程 http blog hokolinks com how to implement apple universal links on ios 9 http blog ho
  • 如何将 NSData 转换为多种类型 Int

    我通过 get NSData 获取磁力计调整寄存器 如下所示 lt 00001a1a 4f56f202 00000000 1dfd421b gt 我需要根据我访问的字节将其转换为 Int8 UInt8 Int16 UInt16 文档来源 s
  • 在 Interface Builder 中使用通用类作为自定义视图

    我有一个 UIButton 的自定义子类 import UIKit IBDesignable class MyButton UIButton var array String 它是 IBDesignable 我已将其设置为故事板中按钮之一的
  • 如何在代码中更改 UIBarButtonItem 的样式

    我正在使用 UIBarButtonSystemItemPlay 播放我的音频文件 我想在单击它时动态更改它的样式 可以吗 如果可以 请帮助我 这是我的代码 其中 playPause 是 UIBarButtonSystemItemPlay 的
  • 设置应用程序默认的iOS本地通知样式

    从 iOS 5 开始 有两种通知样式 横幅和警报 旧 样式 用户可以在设置中为每个应用程序设置使用哪种样式 但是 现在默认情况似乎是通知以横幅样式显示 我使用本地通知来提醒 现在 将发生的事件 横幅出现后不久就会消失 而且还不够明显 人们可
  • iPhone 5 - 新图像必须遵循什么命名约定?

    新 iPhone 5 必须加载新图像的命名约定是什么 我们看到设备必须加载 3 个默认图像 Default png email protected cdn cgi l email protection and email protected
  • UICollectionView cellForItemAtIndexPath 未注册单元格

    我正在尝试使用UICollectionViewCell 因为我想显示的只是一张图像 我可以使用将图像添加到单元格中UIColor colorWithImage on the UICollectionViewCell s contentVie
  • 可可豆荚图表未出现(Swift 4)

    我的图表未使用此条形图显示任何条形 我已成功导入图表可可豆荚 目前没有运行时错误 图表中唯一显示的是描述标签 import UIKit import Charts class ViewController UIViewController
  • 在 ARSCNView 中加载大型 3d 对象 .scn 文件 Aspect 适合屏幕 ARKIT Swift iOS

    我正在使用 3d 模型开发 ARKit 应用程序 为此 我使用了 3D 模型并添加了用于移动 旋转和缩放 3D 模型的手势 现在我只面临 1 个问题 但我不确定这个问题是否与什么有关 3d 模型是否存在问题 或者我的程序是否缺少任何内容 问
  • 比较两个图像并找出差异百分比

    我一直在尝试通过图像制作动物识别应用程序 我的方法是将所选图像与图像数组中的其他图像进行比较 并列出相似度超过 90 的所有比较 还有其他方法可以比较两个相似但不相似的图像吗 任何建议 将不胜感激 这些计算还必须运行多次迭代 因此非常需要一
  • 如何在 iOS 上创建图库

    我开始为 iOS 开发一个简单的应用程序 这个应用程序是一些照片的简单画廊 取自网站 我遇到的第一个问题是如何创建图库的视图 The view should be something like this or the Photo App 然
  • iPadOS:通过 NEHotspotConfiguration 连接的网络在一段时间后断开连接

    我的应用程序使用NEHotspotConfigurationManager使用 Wi Fi 将自身连接到特定设备 该设备充当 WPA2 接入点 在较旧的 iOS 版本 iOS 12 及更低版本 中 一切正常 但在 iPadOS iOS 13
  • 在 Objective-C 中导入 Swift 类,-Swift.h 文件未找到

    我有一个用 Objective C 编写的 iOS 项目 我在项目中创建了一个Swift类 成功生成了Swift中访问objective c的桥接头文件 并且运行良好 我的问题是相反的 我想在 Objective C 代码中导入 Swift

随机推荐

  • kotlin,如何返回泛型类型成员变量

    返回泛型类型的成员变量时出错 在 Android 上 不确定是否有任何区别 private var mData T null override fun
  • 适用于 Windows 7 的 Epson OPOS ADK for .NET 驱动程序

    有没有人使用 Epson OPOS ADK for NET for Windows 7 我尝试在 Windows 7 上安装 Windows Vista 驱动程序 因为没有适用于 Windows 7 的驱动程序 但它不起作用 请分享任何可能
  • 您可以将 WCF 服务中的 WSDL 和 XSD 数据结合起来吗?

    是否可以创建一个文件来从 WCF 生成的 WSDL 文件 以及也从此服务生成的任何其他 XSD 文件 生成客户端 我可以使用 svcutil exe 生成一个有效的客户端 同时传递 wsdl 文件和每个 xsd 文件 但我有一个客户正在使用
  • 在 $PATH 中找不到 docker 可执行文件

    尝试在正在运行的 docker compose 容器上运行 Rails 迁移会引发以下错误 docker compose run webapp rails db migrate 错误 无法启动服务 webapp 标头字段值无效 oci 运行
  • 将函数分配给变量时出错

    我有简单的代码如下 var println print println test 它给了我错误 missing argument for parameter 2 in call 我添加了更多参数 println test n 它仍然给我同样
  • 异步 Action api 如何在 scala 的 play 框架 2.2.x 中工作?

    我试图创建异步 api 但响应显示顺序执行 完成步骤 在 chrome 的两个选项卡中打开 url 并且快速地一一击打他们 网址前 localhost 9000 getStar 但执行日志是这样的 info play Listening f
  • 识别R中的时间

    我正在 R 中处理一个具有如下时间变量的数据集 Time data frame X1 c 930 1130 914 1615 X1 的前两位表示小时 后两位表示分钟 我想让 R 将其识别为时间变量 我尝试使用 lubridate hm 函数
  • 如何在不使用 CTE 的情况下从日期范围创建日期列表

    以下链接解释了如何将日期范围转换为日期列表 我使用了这种方法 它工作正常 但查询没有执行 我使用 Maxrecursion 0 来无限 http blog justinstolle com sql turn a date range int
  • NGINX:将非 www https 重定向到 https://www

    我遵循了这个答案https stackoverflow com a 28068250 3108268但它仅从 http 重定向到 https 将非 www 重定向到 www 但如果我访问我的网站https example com我收到 您的
  • 如何获取iPhone上的WIFI网关地址? [复制]

    这个问题在这里已经有答案了 我需要获取与 iPhone 连接的 wifi 网络的网关地址 有人知道如何得到它吗 只是为了澄清一下 我正在寻找此屏幕的信息 Thanks 添加到您的项目route h文件来自http opensource ap
  • ConcurrentHashMap 中的分段

    我是 Java 世界的新手 我在探索 ConcurrentHashMap API 时发现了这一点 static final int DEFAULT INITIAL CAPACITY 16 static final float DEFAULT
  • 如何使用 Plotly Express 创建子图 [重复]

    这个问题在这里已经有答案了 如果您像我一样 喜欢 Plotly Express 但是当您遇到 Express 返回的数字无法使用 make subplots 的问题时感到沮丧 因为 make subplots 接受的是迹线而不是数字 在这篇
  • 允许 RSU 在 Veins 中接收消息

    我正在尝试在 Veins OMNeT SUMO 上实现一个非常简单的场景 只需三辆车和一个独特的固定 RSU 但我是 Veins 的新手 尽管有大量文档 但我无法很好地移动 常见问题解答和教程我已经读过 我的起点是默认的 TraCI 场景演
  • 库中的 CodeIgniter 验证不接受回调

    我的问题如下 我正在编写一个登录库 该库有一个函数 validation 它使用验证库来验证数据 使用正常的验证方法可以正常工作 但使用回调函数就行不通 它不被称为 我这样称呼它 this gt CI gt form validation
  • 使用 Python 通过 SSH 从服务器读取文件

    我正在尝试使用 Python 中的 SSH 从服务器读取文件 我正在使用 Paramiko 进行连接 我可以连接到服务器并运行类似的命令cat filename并从服务器取回数据 但我尝试读取的某些文件大小约为 1 GB 或更大 如何使用P
  • 使用 WebApi 和 ODataQueryOptions 实现 $select

    我正在尝试使用 ODataQueryOptions 通过自定义 DAL 实现一些 OData 功能 我的 DAL 使用设计时生成的类型化数据表 通过拦截 ODataQueryOptions 的 SelectExpand 属性 我可以让 DA
  • 具有部分更新的实体框架验证

    我将 Entity Framework 5 0 与 DbContext 和 POCO 实体一起使用 有一个包含 3 个属性的简单实体 public class Record public int Id get set public stri
  • 为什么从 ResourceBundle.getBundle 检索字符串时出现无法理解的字符

    请告诉我如何解决这个问题 Locale locale new Locale language ResourceBundle messages ResourceBundle getBundle i18n messages locale utf
  • C++ 运算符歧义

    请原谅我 因为我对 C 相当陌生 但我在运算符歧义方面遇到了一些麻烦 我认为它是特定于编译器的 适用于在我的桌面上编译的代码 但是 它无法在我的笔记本电脑上编译 我想我知道出了什么问题 但我没有看到一个优雅的解决方法 如果我犯了一个明显的错
  • CMSampleBufferGetImageBuffer 中的内存泄漏

    我得到了一个UIImage from a CMSampleBufferRef每 N 个视频帧进行视频缓冲 例如 void imageFromVideoBuffer void UIImage image completion CMSample