从图像创建视频时收到内存警告

时间:2015-12-24 12:32:07

标签: ios objective-c iphone video avfoundation

我正在处理来自图像的创建视频,并且它的工作非常好,但是在iPhone 4s中,不正常的应用程序崩溃了。请查看我的代码并提供您的建议。

- (void)createMovieFromImages:(NSArray *)images withCompletion:(CEMovieMakerCompletion)completion;
{
    self.completionBlock = completion;

    [self.assetWriter startWriting];
    [self.assetWriter startSessionAtSourceTime:kCMTimeZero];

    dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);

    __block NSInteger i = 0;

    NSInteger frameNumber = [images count];

    [self.writerInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^{
        while (YES){
            if (i >= frameNumber) {
                break;
            }
            if ([self.writerInput isReadyForMoreMediaData]) {

                CVPixelBufferRef sampleBuffer = [self newPixelBufferFromCGImage:[[images objectAtIndex:i] CGImage]];

                if (sampleBuffer) {
                    if (i == 0) {
                        [self.bufferAdapter appendPixelBuffer:sampleBuffer withPresentationTime:kCMTimeZero];
                    }else{
                        CMTime lastTime = CMTimeMake(i-1, self.frameTime.timescale);
                        CMTime presentTime = CMTimeAdd(lastTime, self.frameTime);
                        [self.bufferAdapter appendPixelBuffer:sampleBuffer withPresentationTime:presentTime];
                    }
                    CFRelease(sampleBuffer);
                    i++;
                }
            }
        }

        [self.writerInput markAsFinished];
        [self.assetWriter finishWritingWithCompletionHandler:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                self.completionBlock(self.fileURL);
            });
        }];

        CVPixelBufferPoolRelease(self.bufferAdapter.pixelBufferPool);
    }];
}


- (CVPixelBufferRef)newPixelBufferFromCGImage:(CGImageRef)image
{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];

    CVPixelBufferRef pxbuffer = NULL;

    CGFloat frameWidth = [[self.videoSettings objectForKey:AVVideoWidthKey] floatValue];
    CGFloat frameHeight = [[self.videoSettings objectForKey:AVVideoHeightKey] floatValue];


    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
                                          frameWidth,
                                          frameHeight,
                                          kCVPixelFormatType_32ARGB,
                                          (__bridge CFDictionaryRef) options,
                                          &pxbuffer);

    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

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

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(pxdata,
                                                 frameWidth,
                                                 frameHeight,
                                                 8,
                                                 4 * frameWidth,
                                                 rgbColorSpace,
                                                 (CGBitmapInfo)kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);
    CGContextConcatCTM(context, CGAffineTransformIdentity);
    CGContextDrawImage(context, CGRectMake(0,
                                           0,
                                           CGImageGetWidth(image),
                                           CGImageGetHeight(image)),
                       image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}

我已经通过了图片阵列并获得了视频,但它在iPhone 4s中崩溃请帮帮我。

1 个答案:

答案 0 :(得分:1)

由于以下某些原因,此问题变得越来越普遍:

  1. “iPhone 4S拥有512 MB的DDR2 RAM”(wiki),以及操作系统的众多流程和他们自己的硬件需求,以及设备的使用年限(磨损) iPhone 4s不太可能像这样苛刻。
  2. 这个问题(ios app maximum memory budget)假设应用程序在任何给定时间都应该消耗不超过200MB(安全保存在120MB左右)的内存。
  3. 要尝试使其工作,请在后台线程上放置与用户界面相关的任意数量的功能 。您的整个- (CVPixelBufferRef)newPixelBufferFromCGImage:(CGImageRef)image将作为方法- (void)createMovieFromImages:(NSArray *)images...

    在主线程上处理

    无法保证将这些方法放在后台线程上会起作用,但值得尝试。如果您不了解线程,则以下问题/答案/链接有一些与线程相关的相关兴趣点,即使您对开发人员有兴趣,也有一些兴趣:

    1. GCD - main vs background thread for updating a UIImageView
    2. NSOperation and NSOperationQueue working thread vs main thread
    3. http://pinkstone.co.uk/how-to-execute-a-method-on-a-background-thread-in-ios/