本文首发地址:开源实践网:iOS使用CoreImage截图的crash定位和解决
公司的业务上有对直播中的视频截图的需求,我们的实现是使用CoreImage将视频帧数据转成图片。业务实现上没什么大的难点,但是上线以后,buggly上统计的崩溃中,截图的崩溃成了一个top崩溃。该crash崩溃到系统的库中,比较难解决,只能通过详细的分析和不断的尝试修改。解决了以后,将分析过程和解决方案记录一下,为其他的同学遇到相关问题时提供思路。
一、崩溃堆栈
CoreImage CI::GLContext::init() + 212
CoreImage CI::GLContext::GLContext(CI::GLContext::ShareContextInfo, CGColorSpace, CGColorSpace, CI::PixelFormat, bool, unsigned long, bool, bool) + 496
CoreImage CI::GLContext::GLContext(CI::GLContext::ShareContextInfo, CGColorSpace, CGColorSpace, CI::PixelFormat, bool, unsigned long, bool, bool) + 24
CoreImage [CIContext(Internal) internalContextWithEAGLContext:options:] + 628
CoreImage -[CIContext initWithOptions:] + 596
CoreImage +[CIContext contextWithOptions:] + 44
2、问题分析和定位
- 从堆栈上看,该崩溃崩溃到系统库中,没有较多的有用信息,唯一有点提示的是使用了opengl的方式
- 从api的使用方式上看,调用[CIContext contextWithOptions:nil] 没有任何异常
CIImage *rusultImage = [CIImage imageWithCVPixelBuffer:_captureFrame];
CIContext *context = [CIContext contextWithOptions : nil];
CGImageRef videoImage = [context
createCGImage:rusultImage
fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(_captureFrame), CVPixelBufferGetHeight(_captureFrame))];
UIImage *image = [UIImage imageWithCGImage:videoImage];
CGImageRelease(videoImage);
3.从buggly的崩溃分析看,用户的剩余可用内存较低。
3、尝试解决
方案一
怀疑是业务在后台截图导致的崩溃,理论基础:iOS不能在后台使用opengl,这个在苹果的文档中有明确指出。
修复方案,在底层代码中加入前后台判断逻辑,在后台的情况不生成image,直接返回nil
方案二
在 CIContext 创建的时候,我们可以给它设置为基于 GPU 还是 CPU。我们强制设置为CPU,设置代码如下:
contentx = [CIContext contextWithOptions : @{kCIContextUseSoftwareRenderer : @(YES)}]
理论基础:
Core Image 的另外一个优势,就是可以根据需求选择 CPU 或者 GPU 来处理。在 CIContext 创建的时候,我们可以给它设置为基于 GPU 还是 CPU。
基于 GPU 的话,处理速度更快。以为利用了 GPU 的硬件并行优势。可以使用 OpenGL ES 或者 Metal 来渲染图像。这种方式 CPU 完全没有负担,应用程序的运行循环不会受到图像渲染的影响。
但是 GPU 受限于硬件纹理尺寸,而且如果你的程序在后台继续处理和保存图片的话,那么需要使用 CPU。因为当应用切换到后台状态时,GPU 处理会被打断。使用 CPU 渲染的 iOS 会采用 GCD 来对图像进行渲染。这保证了 CPU 渲染在大部分情况下更可靠,比 GPU 渲染更容易使用,可以在后台实现渲染过程。
综上,对于复杂图像滤镜,使用 GPU 更好。但如果在处理视频过程中,保存文件或保存照片到照片库中时,为避免程序进入后台对图片保存造成影响,这时应该使用 CPU 进行渲染。
用官方的一句话来描述再合适不过了:
CPU is still what will give you the best fidelity where as the GPU will give you the best performance.
大体意思:GPU 总是能提供最好的性能,而 CPU 能给你提供最好的精确性。
4、最终解决方案
参考:iOS使用CoreImage截图的crash定位和解决
小而美的站点,跪求 注册 点赞 评论 三连









网友评论