2015-06-30 113 views
3

我試圖獲得一個簡單的渲染相機輸出到金屬層管道,它在Objective-C(有MetalVideoCapture示例應用程序)中工作得很好,但當我嘗試將其翻譯爲swift時,似乎會出現一些格式不正常的情況。我ultrasimple捕獲緩衝看起來像這樣(忽略缺乏消毒的...)使用CVMetalTextureCacheCreateTextureFromImage在Swift中將CMSampleBuffer轉換爲CVMetalTexture

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) { 
    var error: CVReturn! = nil 
    let sourceImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 
    let width = CVPixelBufferGetWidth(sourceImageBuffer!) 
    let height = CVPixelBufferGetHeight(sourceImageBuffer!) 
    var outTexture: CVMetalTextureRef? = nil 

    error = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache!, sourceImageBuffer!, nil, MTLPixelFormat.BGRA8Unorm, width, height, 0, &outTexture!) 

    if error != nil { 
     print("Error! \(error)") 
    } 

    let videoTexture = CVMetalTextureGetTexture(outTexture!) 
    self.imageTexture = videoTexture! 
} 

哪裏videoTextureCache是​​var videoTextureCache: CVMetalTextureCache? = nil

但它給了我Cannot invoke 'CVMetalTextureCacheCreateTextureFromImage' with an argument list of type '(CFAllocator!, CVMetalTextureCache, CVImageBuffer, nil, MTLPixelFormat, Int, Int, Int, inout CVMetalTextureRef)'

的事情是,如果我替換outTexture零它停止拋出錯誤,但顯然這不會幫助我。根據函數的參考,我需要UnsafeMutablePointer?>作爲最後一個值。我不知道如何得到。

回答

3

嘗試分配你的textureCache提前,這裏是我的成員變量使用:通過

CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _context.device, nil, &_videoTextureCache) 

其中

var _videoTextureCache : Unmanaged<CVMetalTextureCacheRef>? 

然後我分配textureCache在初始化方法_context.device是MTLDevice。然後,在captureOutput方法中,我使用以下(請注意,此處不包含錯誤檢查)

var textureRef : Unmanaged<CVMetalTextureRef>? 
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache!.takeUnretainedValue(), imageBuffer, nil, MTLPixelFormat.BGRA8Unorm, width, height, 0, &textureRef) 

我希望這有助於!

+0

太棒了!我也一直在摔跤 - 這要感謝一萬美元:) –

+0

嗨,你有沒有更新Swift 3? – jperl

0

僅供參考,我創建了一個演示項目,將Y和CbCr平面轉換爲單個RBG紋理,並將Metal Performance Shader應用於結果。

你可以在我的博客在這裏讀到它:http://flexmonkey.blogspot.co.uk/2015/07/generating-filtering-metal-textures.html

乾杯!

西蒙

+0

嘿西蒙!你爲什麼沒有像RGBA/BGRA那樣請求緩衝區像素格式?這不會節省你的談話嗎? –

+0

你是對的! 'videoSettings = [kCVPixelBufferPixelFormatTypeKey:Int(kCVPixelFormatType_32BGRA)]'是更直接的解決方案。 –

+0

任何機會,你可以更新項目(我認爲它可能會簡化它很多)。如果你這樣做 - 它會很棒! :) –

0

更新@ peacer212答案斯威夫特3.

你不需要UnmanagedtakeUnretainedValue了。所以代碼應該是:

var textureCache: CVMetalTextureCache? 

... 
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _context.device, nil, &_videoTextureCache) 

... 

var textureRef : CVMetalTexture? 
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache!, imageBuffer, nil, .bgra8Unorm, width, height, 0, & textureRef) 
相關問題