0

いくつかの UIImage があり、それらからビデオを作成したいと考えています。

これに基づくソリューションを使用しています

UIImages からビデオを作成します。私の場合、30 fps のビデオを作成したいと考えています。つまり、すべての画像は 1/30 秒です。

そのページに記載されているように、ビデオの保存を開始するようにすべてを設定した後、1 つの画像をムービーに保存するメソッドを作成しました。このメソッドはループによって呼び出されます。何かのようなもの:

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

このように見てください。画像の配列があります (多くのメモリを消費するもの)。これらの画像のそれぞれのコピーを作成し、そのコピーを完成したムービーに保存しています。そのため、要件は本質的に最初の 2 倍になります。フレームを追加した後、各フレームを解放した場合はどうですか? これは、同じサイズ (または、おそらく多少大きいが、以前よりも小さい) のメモリ使用量になる可能性があることを意味します。

于 2012-06-22T19:35:42.367 に答える