Ios 从AVFoundation相机流生成mipmapped MTLTexture

Ios 从AVFoundation相机流生成mipmapped MTLTexture,ios,opengl-es,avfoundation,metal,Ios,Opengl Es,Avfoundation,Metal,我正在使用AVFoundation获取相机流。 我使用此代码从以下位置获取MTLTextures: - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CVPixelBufferRef pixelBuffer = CMSampl

我正在使用AVFoundation获取相机流。 我使用此代码从以下位置获取MTLTextures:

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

  id<MTLTexture> texture = nil;

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

    MTLPixelFormat pixelFormat = MTLPixelFormatBGRA8Unorm;

    CVMetalTextureRef metalTextureRef = NULL;

    CVReturn status = CVMetalTextureCacheCreateTextureFromImage(NULL, _textureCache, pixelBuffer, NULL, pixelFormat, width, height, 0, &metalTextureRef);
    if(status == kCVReturnSuccess)
    {
     texture = CVMetalTextureGetTexture(metalTextureRef);

     if (self.delegate){

        [self.delegate textureUpdated:texture];
      }
      CFRelease(metalTextureRef);
    }
  }
}
还有第三个参数名为“TextureAttributes”,我认为可以指定我想要mipmapped纹理,但我在文档中找不到确切的单词。我也没有找到传递其他内容而不是NULL的源代码


OpenGLESforiOS中,有类似的方法,参数相同,文档中也没有文字。

没有直接获得mipmapped纹理的方法,但您可以很容易地自己生成一个

首先,使用金属设备创建一个空的金属纹理,该纹理的大小和格式与现有纹理相同,但具有完整的mipmap链

使用MTLCommandBuffer对象创建blitEncoder对象

使用blitEncoder将相机纹理复制到空纹理。destinationLevel应为零,因为您仅复制顶级mipmap

最后,使用blitEncoder通过调用generateMipmapsForTexture生成所有mip级别


最后,您将从带有完整mip链的相机中获得一个金属纹理。

刚刚收到金属工程师的答复。这里有一句话:

否,无法从纹理生成mipmapped纹理 直接使用CVPixelBuffer。
CVPixelBuffer图像通常具有线性/跨步布局,因为非GPU硬件块可能与这些硬件块交互,并且大多数GPU 硬件仅支持从平铺纹理进行mipmapping。你需要 发出blit以将线性MTLTexture复制到专用 MTLTexture,然后生成mipmap


至于textureAttributes,只支持一个键:
KCVMetalTextureCamaximumTextureAgeKey

,这正是我现在正在做的。但我有一个框架下降这样做。我仍然认为这在其他方面是可能的。“TextureAttributes”可能可以做到这一点。您认为这种方法一定存在的原因是什么?相机图像通常不需要mipmap,当它们需要mipmap时,仍然需要生成它们(因此,要做的工作与您已经做的工作相同)。如果文档中没有提到它,那么它似乎不太可能存在。如果使用BLITAd编码器生成MIP映射太慢,我会考虑通过标准GPU渲染来生成它们。这种操作的强度并不是你所期望的那样,你是对的,所以我给你悬赏。但我会接受我的答案,因为这是苹果公司证明的。
CVMetalTextureCacheCreateTextureFromImage(NULL, _textureCache, pixelBuffer, NULL, pixelFormat, width, height, 0, &metalTextureRef);