0

我有几个 UIImages,我想用它们创建一个视频。

我使用了基于此的解决方案

从 UIImages 创建视频。就我而言,我想创建一个 30 fps 的视频。因此,每张图像都是 1/30 秒。

在设置完所有内容以开始保存视频后,如该页面所述,我创建了一个将一个图像保存到电影的方法,该方法由循环调用。就像是:

for (int i=0; i<[self.arrayOfFrames count]; i++ {
  UIImage *oneImage = [self.arrayOfFrames objectAtIndex:i];
  [self saveOneFrame:oneImage atTime:i];
}

方法是

-(void)saveOneFrame:(UIImage *)imagem atTime:(NSInteger)time {
    // I have tried this autorelease pool to drain memory after the method is finished
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    CVPixelBufferRef buffer = NULL;

    buffer = [self pixelBufferFromCGImage:imagem.CGImage size:imagem.size];

    BOOL append_ok = NO;
    int j = 0;
    while (!append_ok && j < 30) 
    {
        if (adaptor.assetWriterInput.readyForMoreMediaData) 
        {
            printf("appending %d attemp %d\n", time, j);

            CMTime oneFrameLength = CMTimeMake(1, 30.0f );  // one frame = 1/30 s
            CMTime lastTime;
            CMTime presentTime;

            if (time == 0) {
                presentTime = CMTimeMake(0, self.FPS);
            } else {
                lastTime = CMTimeMake(tempo-1, self.FPS);
                presentTime = CMTimeAdd(lastTime, duracaoUmFrame);

            }
            // this will always add 1/30 to every new keyframe
            CMTime presentTime = CMTimeAdd(lastTime, oneFrameLength);

            append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
            CVPixelBufferPoolRef bufferPool = adaptor.pixelBufferPool;
            NSParameterAssert(bufferPool != NULL); 

            [NSThread sleepForTimeInterval:0.05];
        } 
        else 
        {
            printf("adaptor not ready %d, %d\n", time, j);
            [NSThread sleepForTimeInterval:0.1];
        }
        j++;
    }
    if (!append_ok) {
        printf("error appending image %d times %d\n", time, j);
    }
    CVBufferRelease(buffer);
    [pool drain]; // I have tried with and without this autorelease pool in place... no difference

}

在将 50 帧保存到电影后,应用程序会在没有任何警告的情况下直接退出......

这是另一种方法:

-(CVPixelBufferRef) pixelBufferFromCGImage:(CGImageRef)image size:(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, (CFDictionaryRef) options, 
                                          &pxbuffer);
    status=status;//Added to make the stupid compiler not show a stupid warning.
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

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

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
                                                 size.height, 8, 4*size.width, rgbColorSpace, 
                                                 kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);

    //CGContextTranslateCTM(context, 0, CGImageGetHeight(image));
    //CGContextScaleCTM(context, 1.0, -1.0);//Flip vertically to account for different origin

    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
                                           CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}

我运行仪器并且在电影开始保存之前没有检测到任何泄漏或夸大的内存使用情况。

任何线索?


笔记:

查看设备日志后,我发现:

<Notice>: (UIKitApplication:com.myID.myApp[0xc304]) Bug: launchd_core_logic.c:3732 (25562):3
<Notice>: (UIKitApplication:com.myID.myApp[0xc304]) Assuming job exited: <rdar://problem/5020256>: 10: No child processes
<Warning>: (UIKitApplication:com.myID.myApp[0xc304]) Job appears to have crashed: Segmentation fault: 11
<Warning>: Application 'myApp' exited abnormally with signal 11: Segmentation fault: 11
4

2 回答 2

0

也许您已经尝试过,但这有帮助吗?

最后,解决方案是重新启动 iPhone,因为某些数据已损坏。重启后一切正常。

应该想到经典的“你试过把它关掉再打开吗?”

于 2012-06-22T18:02:34.120 回答
0

这样看,您有一组图像(占用大量内存的东西)。您正在制作每个图像的副本并将副本保存到完成的电影中。因此,您的要求基本上是您开始时的两倍。如果在添加框架后释放每个框架会怎样?这意味着您最终可能会获得相同大小(或可能稍大,但仍小于您所拥有的)内存使用量。

于 2012-06-22T19:35:42.367 回答