extension MTLTexture {
func toCVPixelBufferInBGRA8() -> CVPixelBuffer? {
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
var pixelBufferOut: Unmanaged<CVPixelBuffer>?
if let iosurface = self.iosurface {
CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, iosurface, attrs, &pixelBufferOut)
}
guard let pixelBuffer = pixelBufferOut?.takeRetainedValue() else {
return nil
}
CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly)
defer {
CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)
}
let width = vImagePixelCount(CVPixelBufferGetWidth(pixelBuffer))
let height = vImagePixelCount(CVPixelBufferGetHeight(pixelBuffer))
let srcBytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let srcBaseAddress = CVPixelBufferGetBaseAddress(pixelBuffer)
var srcBuffer = vImage_Buffer(data: srcBaseAddress, height: height, width: width, rowBytes: srcBytesPerRow)
if let src = srcBaseAddress?.assumingMemoryBound(to: UInt16.self) {
var n = 0
n = 1
print("srcBaseAddress", src[0 + 4 * n], src[1 + 4 * n], src[2 + 4 * n], src[3 + 4 * n]);
n = 1334
print("srcBaseAddress", src[0 + 4 * n], src[1 + 4 * n], src[2 + 4 * n], src[3 + 4 * n]);
}
let dstBytesPerRow = Int(width) * 5
guard let dstBaseAddress = malloc(Int(height) * dstBytesPerRow) else {
return nil
}
var dstBuffer = vImage_Buffer(data: dstBaseAddress, height: height, width: width, rowBytes: dstBytesPerRow)
let error = vImageConvert_ARGB2101010ToARGB8888(&srcBuffer, &dstBuffer, 0, 1023, [0, 1, 2, 3], vImage_Flags(kvImageNoFlags))
guard error == kvImageNoError else {
free(dstBaseAddress)
return nil
}
var dstCVPixelBuffer: CVPixelBuffer?
let releaseCallback: CVPixelBufferReleaseBytesCallback = {_, pointer in
if let pointer = pointer {
free(UnsafeMutableRawPointer(mutating: pointer))
}
}
guard CVPixelBufferCreateWithBytes(nil, Int(width), Int(height), kCVPixelFormatType_32BGRA, dstBaseAddress, dstBytesPerRow, releaseCallback, nil, attrs, &dstCVPixelBuffer) == kCVReturnSuccess else {
free(dstBaseAddress)
return nil
}
let dst = dstBaseAddress.assumingMemoryBound(to: UInt8.self)
var n = 0
n = 1
print("dstBaseAddress", dst[0 + 4 * n], dst[1 + 4 * n], dst[2 + 4 * n], dst[3 + 4 * n]);
n = 1334
print("dstBaseAddress", dst[0 + 4 * n], dst[1 + 4 * n], dst[2 + 4 * n], dst[3 + 4 * n]);
print("")
return dstCVPixelBuffer
}
}
I have few print statement and you can use the output to see the color value. When the metal texture is red and pixel format is kCVPixelFormatType_40ARGBLEWideGamut
, the color value is B=30144 G=25216 R=54592 A=57216. After the conversion, the color in kCVPixelFormatType_32BGRA is 255 126 13 128. But I do not know which is A, R, G, B.