【问题标题】:Receive memory warning when I create video from images当我从图像创建视频时收到内存警告
【发布时间】:2015-12-24 12:32:07
【问题描述】:

我正在使用从图像创建视频,它工作得很好,但不幸的是,应用程序在 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 中崩溃了,请帮助我。

【问题讨论】:

    标签: ios objective-c iphone video avfoundation


    【解决方案1】:

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

    1. “iPhone 4S 有 512 MB 的 DDR2 RAM”(wiki) iPhone 4s 不太可能具备如此苛刻的要求。
    2. 这个问题 (ios app maximum memory budget) 假设应用程序在任何给定时间消耗的内存不超过 200MB(为了安全起见,保持在 120MB 左右)。

    要尝试完成这项工作,请在后台线程上放置尽可能多的与用户界面相关的功能。你的整个- (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/

    【讨论】:

      猜你喜欢
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 2013-03-12
      • 2011-04-30
      相关资源
      最近更新 更多