2014-11-04 30 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