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 бит без знака Int). Это зависит от формата видео. Скорее всего, это 8 бит.
Обновление на форматы буфера:
Вы можете указать формат при инициализации экземпляра AVCaptureVideoDataOutput
. Вы в основном есть выбор:
- BGRA: одну плоскость, где значения синий, зеленый, красный и альфа сохраняются в 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)
Основной буфер видеопикселя не содержит информации об одном пикселе, вместо этого он содержит информацию о пикселях всего пикселя, захваченного из сцены (матрица растровых изображений пикселей). Вы хотите иметь значения RGB для каждого пикселя внутри буфера? –
Возможный дубликат [Как преобразовать вызов CVPixelBufferGetBaseAddress в Swift?] (Http://stackoverflow.com/questions/29814143/how-to-convert-cvpixelbuffergetbaseaddress-call-to-swift). –