10

iPhoneアプリでCGBitmapContextCreateImageを使用すると問題が発生します。

私はAVFoundationFrameworkを使用して、この方法を使用してカメラフレームを取得しています。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer,0);
    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGImageRef newImage = CGBitmapContextCreateImage(newContext);
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
    CGContextRelease(newContext);
    CGColorSpaceRelease(colorSpace);

    UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight];
    self.imageView.image = image;

    CGImageRelease(newImage);

} 

ただし、実行中にデバッグコンソールにエラーが表示されます。

<Error>: CGDataProviderCreateWithCopyOfData: vm_copy failed: status 2.

誰かがこれを見たことがありますか?行をコメントアウトすることにより、問題の行を次のように絞り込みました。

CGImageRef newImage = CGBitmapContextCreateImage(newContext);

しかし、私はそれを取り除く方法がわかりません。機能的には、うまく機能します。明らかに、CGImageが作成されていますが、他の部分に影響を与えないように、エラーの原因を知る必要があります。

どうもありがとう。どんな助け/アドバイスも素晴らしいでしょう!ブレット

4

1 に答える 1

11

免責事項: これは純粋な憶測です。もう違います。

vm_copy()仮想メモリをある場所から別の場所にコピーするためのカーネル呼び出しです ( manpage )。

取得する戻り値は、KERN_PROTECTION_FAILURE、「ソース リージョンが読み取りに対して保護されているか、宛先リージョンが書き込みに対して保護されています」です。

したがって、何らかの理由で CGDataProviderCreateWithCopyOfData はこれを呼び出してメモリをコピーし、失敗します。おそらく、最初に高速な方法として vm_copy を試してから、低速な方法にフォールバックするだけです (すべてが機能すると言うため)。

メモリのチャンクをmallocbaseAddress から自分のメモリに memcpy し、それを使用してイメージを作成すると、警告は消えます。そう:

uint8_t *tmp = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
int bytes = ... // determine number of bytes from height * bytesperrow
uint8_t *baseAddress = malloc(bytes);
memcpy(baseAddress,tmp,bytes);

// unlock the memory, do other stuff, but don't forget:
free(baseAddress);
于 2010-07-30T01:07:05.243 に答える