2014-11-04 33 views
3

我正在使用AVFoundation获取相机流。 我使用这个代码从MTLTextures:从AVFoundation相机流生成mipmaped 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); 
    } 
    } 
} 

它工作正常,除了生成MTLTexture对象不mipmaped(只有一个MIP水平)。 在此呼吁:

CVMetalTextureCacheCreateTextureFromImage(NULL, _textureCache, pixelBuffer, NULL, pixelFormat, width, height, 0, &metalTextureRef); 

有一个称为“textureAtributes”,我认为这是可以指定我想mipmaped质地第三个参数,但我没有找到文件究竟是什么的任何单词去那里。我也没有找到一个源代码,其中传递了其他内容,而不是NULL。

OpenGLES的iOS有类似的方法,用相同的参数,并在文档还没有的话。

回答

2

刚刚接到了来自金属工程师here答案。这是一个报价:

不,不可能直接从 CVPixelBuffer生成mipmapped纹理。
CVPixelBuffer图像通常具有直链/步幅布局,作为非GPU硬件块可能与那些进行交互,并且最GPU 硬件仅支持从平铺纹理mipmapping贴图。你需要 问题上的blit从线性MTLTexture复制到私人 MTLTexture你自己创造的,然后生成的贴图。

至于textureAttributes,只有一个重点支持:kCVMetalTextureCacheMaximumTextureAgeKey

1

没有直接获取mipmapped纹理的方法,但您可以轻松地自己生成一个纹理。

首先使用金属设备创建一个空的金属质感是相同的大小和格式,您现有的质感,但有一个完整的纹理贴图链。 See newTexture documentation

使用您的MTLCommandBuffer对象创建blitEncoder对象。 See blitCommandEncoder documentation

使用blitEncoder从相机纹理复制到空纹理。 destinationLevel应该为零,因为您只复制顶层mipmap。 See copyFromTexture documentation

最后使用blitEncoder通过调用generateMipmapsForTexture来生成所有的mip级别。 See generateMipMapsForTexture documentation

在这段你到底有没有从相机的金属质感,尽显MIP链。

+0

这正是我现在在做。但我有框架下降这样做。我仍然认为这是可能的其他方式。那个“textureAtributes”可能可以做到这一点。 – haawa 2014-11-10 09:57:09

+1

你认为这种方法必须存在吗?摄像机图像通常不需要mipmap,并且当他们这样做时,他们仍然必须生成(因此,您已经在做同样的工作)。如果文档没有提到它,那么它似乎不太可能存在。如果使用BlitEncoder生成mip贴图太慢,我会考虑通过标准GPU渲染来生成它们。这种操作并不是很密集,你应该期望丢帧。 – Muzza 2014-11-11 00:48:21

+0

你说得对,所以我给你赏金。但会接受我的回答,因为它已被苹果证实。 – haawa 2014-11-13 10:27:12