baseAddress
是一个不安全的可变指针或更准确地说是一个UnsafeMutablePointer<Void>
. Void
将指针从转换为更具体的类型后,您可以轻松访问内存:
// Convert the base address to a safe pointer of the appropriate type
let byteBuffer = UnsafeMutablePointer<UInt8>(baseAddress)
// read the data (returns value of type UInt8)
let firstByte = byteBuffer[0]
// write data
byteBuffer[3] = 90
确保使用正确的类型(8、16 或 32 位无符号整数)。这取决于视频格式。很可能是8位。
缓冲区格式更新:
您可以在初始化AVCaptureVideoDataOutput
实例时指定格式。您基本上可以选择:
- BGRA:一个平面,其中蓝色、绿色、红色和 alpha 值分别存储在一个 32 位整数中
- 420YpCbCr8BiPlanarFullRange:两个平面,第一个包含每个像素的字节,具有 Y(亮度)值,第二个包含像素组的 Cb 和 Cr(色度)值
- 420YpCbCr8BiPlanarVideoRange:与 420YpCbCr8BiPlanarFullRange 相同,但 Y 值限制在 16 – 235 范围内(出于历史原因)
如果您对颜色值感兴趣,并且速度(或者说最大帧速率)不是问题,那么请选择更简单的 BGRA 格式。否则采用更有效的原生视频格式之一。
如果您有两个平面,则必须获取所需平面的基地址(参见视频格式示例):
视频格式示例
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(pixelBuffer, 0)
let baseAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0)
let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0)
let byteBuffer = UnsafeMutablePointer<UInt8>(baseAddress)
// Get luma value for pixel (43, 17)
let luma = byteBuffer[17 * bytesPerRow + 43]
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
BGRA 示例
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(pixelBuffer, 0)
let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer)
let int32PerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let int32Buffer = UnsafeMutablePointer<UInt32>(baseAddress)
// Get BGRA value for pixel (43, 17)
let luma = int32Buffer[17 * int32PerRow + 43]
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)