Swift 3: Как получить доступ к значению matrix_float3x3 в 48-байтовых CFData?

Я пытаюсь получить доступ к внутренней матрице после этого ответа.

Запустив приведенную ниже рекомендацию, я смог получить 48-байтовый AnyObject и преобразовать его в CFData.

let camData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil)

Тем не менее, я проверил вывод sampleBuffer в CMSampleBuffer.h:

/*! @constant   kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix
     @abstract  Indicates the 3x3 camera intrinsic matrix applied to the current sample buffer.
     @discussion Camera intrinsic matrix is a CFData containing a matrix_float3x3, which is column-major.
        ....
 */
CM_EXPORT const CFStringRef kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix  // CFData (matrix_float3x3) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_11_0);

Как мне получить доступ к значению в matrix_float3x3 от CFData?

3 ответа

Решение

Это должно работать:

  • Используйте мост от CFData в NSData в Data, а также
  • withUnsafeBytes метод для получения указателя нужного типа на байты данных,
  • .pointee разыменовать указатель.

Пример:

if let camData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) as? Data {
    let matrix: matrix_float3x3 = camData.withUnsafeBytes { $0.pointee }

    // ...

}

Тип указателя ($0 внутри замыкания) выводится из контекста как UnsafePointer<matrix_float3x3>,

Вот обновление ответа Мартина Р. с моментаwithUnsafeBytesбыло объявлено устаревшим:

      if let camData = CMGetAttachment(sampleBuffer, 
                                 key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, 
                                 attachmentModeOut: nil) as? Data {
    let matrix = camData.withUnsafeBytes { $0.load(as: matrix_float3x3.self) }
    ...
}

Это версия ответа Мартина R для objective-c:

CFTypeRef cameraIntrinsicData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil);
if(cameraIntrinsicData != nil){
    CFDataRef cfdr = (CFDataRef)(cameraIntrinsicData);
    matrix_float3x3 camMatrix = (matrix_float3x3 *)(CFDataGetBytePtr(cfdr));
}
Другие вопросы по тегам