baseAddress
是一个不安全的可变指针或更确切地说是一个UnsafeMutablePointer
.将指针转换Void
为更具体的类型后,可以轻松访问内存:
// Convert the base address to a safe pointer of the appropriate type let byteBuffer = UnsafeMutablePointer(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(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(baseAddress) // Get BGRA value for pixel (43, 17) let luma = int32Buffer[17 * int32PerRow + 43] CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
Swift3的更新:
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)! CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0)); let int32Buffer = unsafeBitCast(CVPixelBufferGetBaseAddress(pixelBuffer), to: UnsafeMutablePointer.self) let int32PerRow = CVPixelBufferGetBytesPerRow(pixelBuffer) // Get BGRA value for pixel (43, 17) let luma = int32Buffer[17 * int32PerRow + 43] CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)