ioscore-videoiosurface

CoreVideo / IOSurface: unknown pixel format


I'm trying to capture an IOSurface using both CVPixelBufferCreateWithIOSurface and by reading pixels from IOSurfaceGetBaseAddressOfPlane.

However, on newer devices (iPhone XS), I get an unknown pixel format &wq2 (again, using both IOSurfaceGetPixelFormat and CVPixelBufferGetPixelFormatType).

CVPixelFormatDescriptionCreateWithPixelFormatType returns the following:

@"{\n    BitsPerComponent = 10;\n    ComponentRange = FullRange;\n    ContainsAlpha = 1;\n    ContainsGrayscale = 0;\n    ContainsRGB = 1;\n    ContainsYCbCr = 0;\n    PixelFormat = 645346401;\n    Planes =     (\n                {\n            BitsPerBlock = 64;\n            CompressionType = 2;\n            TileHeight = 16;\n            TileWidth = 16;\n        }\n    );\n}"

My code works perfectly on older devices (where it returns BGRA as the pixel format), but breaks down on what I assume are newer devices. How can I unmarshal the pixels from this undocumented format.


Solution

  • I have a bad habit of answering my own questions.

    To convert this IOSurface to say an IOSurface with a known pixel type, an IOAccelerator should be used.

        CFMutableDictionary dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);;
        char pixelFormat[4] = {'A', 'R', 'G', 'B'};
    
        CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bytesPerRow));
        CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bytesPerElement));
        CFDictionarySetValue(dict, kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
        CFDictionarySetValue(dict, kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
        CFDictionarySetValue(dict, kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat));
        CFDictionarySetValue(dict, kIOSurfaceAllocSize, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bufferSize));
        IOSurfaceRef surface = IOSurfaceCreate(dict);
    
        auto const didCreateAccelerator = IOSurfaceAcceleratorCreate(kCFAllocatorDefault, 0, &accelerator);