1

ビデオ フレームをクロップするカスタム ビデオ コンポジターを実装しています。現在、これを行うために Core Graphics を使用しています。

-(void)renderImage:(CGImageRef)image inBuffer:(CVPixelBufferRef)destination {
    CGRect cropRect = // some rect ...
    CGImageRef currentRectImage = CGImageCreateWithImageInRect(photoFullImage, cropRect);

    size_t width = CVPixelBufferGetWidth(destination);
    size_t height = CVPixelBufferGetHeight(destination);

    CGContextRef context = CGBitmapContextCreate(CVPixelBufferGetBaseAddress(destination),       // data
                                             width,
                                             height,
                                             8,                                              // bpp
                                             CVPixelBufferGetBytesPerRow(destination),
                                             CGImageGetColorSpace(backImage),
                                             CGImageGetBitmapInfo(backImage));

    CGRect frame = CGRectMake(0, 0, width, height);
    CGContextDrawImage(context, frame, currentRectImage);
    CGContextRelease(context);
}

Metal API を使用してこれを行うにはどうすればよいですか? それははるかに速いはずですよね?Accelerate Framework (具体的には vImage) の使用についてはどうですか? それはもっと簡単でしょうか?

4

2 に答える 2

3

わかりました、これがあなたにとって役立つかどうかはわかりませんが、それでも. 次のコードを確認してください。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
  CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

  id<MTLTexture> textureY = nil;

  {
    size_t width = CVPixelBufferGetWidth(pixelBuffer);
    size_t height = CVPixelBufferGetHeight(pixelBuffer);

    MTLPixelFormat pixelFormat = MTLPixelFormatBGRA8Unorm;

    CVMetalTextureRef texture = NULL;
    CVReturn status = CVMetalTextureCacheCreateTextureFromImage(NULL, _textureCache, pixelBuffer, NULL, pixelFormat, width, height, 0, &texture);
    if(status == kCVReturnSuccess)
    {
      textureY = CVMetalTextureGetTexture(texture);
      if (self.delegate){
        [self.delegate textureUpdated:textureY];
      }
      CFRelease(texture);
    }
  }
}

このコードを使用CVPixelBufferRefして MTLTexture に変換します。その後、おそらくそれを作成blitCommandEncoderして使用する必要があります

func copyFromTexture(sourceTexture: MTLTexture, sourceSlice: Int, sourceLevel: Int, sourceOrigin: MTLOrigin, sourceSize: MTLSize, toTexture destinationTexture: MTLTexture, destinationSlice: Int, destinationLevel: Int, destinationOrigin: MTLOrigin)

その中で、トリミングされた長方形を選択して、他のテクスチャにコピーできます。

次のステップは、生成されたものを変換しMTLTexturesCVPixelBufferRefsからビデオを作成することですが、残念ながらその方法はわかりません。

あなたが思いついたことを本当に聞きたいです。乾杯。

于 2015-04-27T08:01:27.800 に答える