首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CGContextDrawImage崩溃

CGContextDrawImage崩溃
EN

Stack Overflow用户
提问于 2012-12-08 01:06:09
回答 1查看 2.5K关注 0票数 0

我尝试从CGImage创建CVPixelBufferRef,所以方法如下:

代码语言:javascript
复制
- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
    CGImageRetain(image);
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];
    CVPixelBufferRef pxbuffer = NULL;

    CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
                        CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
                        &pxbuffer);

    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image),
                                                 CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace,
                                                 kCGImageAlphaNoneSkipFirst);
    CGContextRetain(context);
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                               CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
    CGContextRelease(context);
    CGImageRelease(image);
    return pxbuffer;
}

我经常调用这个方法,它用于生成视频帧,25fps。这在大多数情况下都工作得很好,但在某些情况下,它会在下面这行代码中崩溃:

代码语言:javascript
复制
 CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                                   CGImageGetHeight(image)), image);

我已经测试了内存使用率和内存泄漏,一切看起来都很好,但仍然会发生崩溃。

崩溃堆栈:线程6崩溃:

代码语言:javascript
复制
0   ImageIO                         0x39270806 CGImageReadGetBytesAtOffset + 34
1   ImageIO                         0x392707d6 CGImageReadSessionGetBytes + 22
2   ImageIO                         0x39280c3c fill_input_buffer + 148
3   ImageIO                         0x3928003a read_markers + 154
4   ImageIO                         0x3927fd82 consume_markers + 34
5   ImageIO                         0x3927fbd2 _cg_jpeg_consume_input + 66
6   ImageIO                         0x3927fb62 _cg_jpeg_read_header + 38
7   ImageIO                         0x39292782 copyImageBlockSetJPEG + 2346
8   ImageIO                         0x3928953e ImageProviderCopyImageBlockSetCallback + 510
9   CoreGraphics                    0x38e0b9d6 CGImageProviderCopyImageBlockSetWithOptions + 158
10  CoreGraphics                    0x38e0b66a img_blocks_create + 370
11  CoreGraphics                    0x38e07a98 img_data_lock + 1488
12  CoreGraphics                    0x38e06d2a CGSImageDataLock + 126
EN

回答 1

Stack Overflow用户

发布于 2012-12-08 02:26:55

从崩溃堆栈来看,您的映像本身似乎是在其他线程上释放的,可能是在您调用CGImageRetain()之前。您在这里调用CGImageRetain()的事实表明您已经预料到了这一点。但如果是这样的话,保留是不够的,因为它会产生竞争条件。在您尝试保留该图像之前,该图像可能已被销毁。因此,要么CGImageRetain是不必要的,要么它是不够的。在任何一种情况下,它都不应该在这里(也不应该是它的平衡CGImageRelease)。

这表明在其他线程上使用此图像非常危险,这要么表明您以奇怪的方式调用此方法,要么表明您让线程变得过于复杂。例如,如果你直接使用NSThread,你可能让它变得太复杂了。

我会审核您在此映像上的其他保留和释放,并确保它们不会在调用此方法的过程中发生。我很确定这就是正在发生的事情。

附注:您有一个不需要的冗余CGContextRetain/CGContextRelease。当您调用CGBitmapContextCreate()时,它包含了一个保留(它的名称中有"Create“)。也就是说,这只是一个小的性能问题;您已经适当地平衡了它们。但这表明您在其他地方的内存管理可能也很奇怪,因此您应该对其进行审计。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13767685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档