调用 CGContextDrawImage 后内存泄漏

Memory leak after call CGContextDrawImage

提问人:user38931 提问时间:6/9/2020 最后编辑:user38931 更新时间:6/9/2020 访问量:163

问:

我已经阅读了所有 CGContextDrawImage 内存峰值答案,我尝试过,但还没有任何解决方案有效。

这是我的代码,调用CGContextDrawImage后,内存增加10-40MB。我正在使用此代码从图像生成视频,如果我有 200 张图像,应用程序就会崩溃。

循环访问图像:

for(UIImage * img in imageArray)
{

    buffer = [self pixelBufferFromCGImage:[img CGImage] ImageSize:img.size];

    BOOL append_ok = NO;
    int j = 0;
    while (!append_ok) {
        if (adaptor.assetWriterInput.readyForMoreMediaData)  {
            //print out status:
            NSLog(@"Processing video frame (%d,%lu)",frameCount,(unsigned long)[imageArray count]);

            CMTime frameTime = CMTimeMake(frameCount*frameDuration,(int32_t) fps);
            append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
            if(!append_ok){
                NSError *error = videoWriter.error;
                if(error!=nil) {
                    NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
                }
            }
        }
        else {
            printf("adaptor not ready %d, %d\n", frameCount, j);
            [NSThread sleepForTimeInterval:0.1];
        }
    }
    if (!append_ok) {
        printf("error appending image %d times %d\n, with error.", frameCount, j);
    }
    frameCount++;
}

下面是 pixelBufferFromCGImage 函数

- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image ImageSize:(CGSize)size {

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                         nil];
CVPixelBufferRef pxbuffer = NULL;

CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
                                      size.width,
                                      size.height,
                                      kCVPixelFormatType_32ARGB,
                                      (__bridge CFDictionaryRef) options,
                                      &pxbuffer);
if (status != kCVReturnSuccess){
    NSLog(@"Failed to create pixel buffer");
}

CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
                                             size.height, 8, 4*size.width, rgbColorSpace,
                                             kCGImageAlphaPremultipliedFirst);
//kCGImageAlphaNoneSkipFirst);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                       CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
Objective-C 管理内存 泄漏 uiimage

评论

0赞 zrzka 6/9/2020
这回答了你的问题吗?AVAssetWriterInputPixelBufferAdaptor appendPixelBuffer
0赞 zrzka 6/9/2020
查看链接的问题 - 您的代码看起来像是复制和粘贴相同的问题 - 您正在创建,但没有将其发布到循环中的任何地方>(检查)。CVPixelBufferCFRelease(buffer)!= NULL
0赞 user38931 6/11/2020
是的,就是这样。正确答案是 CVPixelBufferRelease(buffer);释放缓冲区
0赞 zrzka 6/11/2020
仅供参考 - 相当于 .唯一的区别是安全的。CVPixelBufferReleaseCFReleaseCVPixelBufferReleaseNULL

答: 暂无答案