IOSurfaces - Artefakty w wideo i niezdolne do chwytania powierzchni wideo

To pytanie 2-częściowe. Mam następujący kod, który chwyta bieżącą powierzchnię wyświetlacza i tworzy wideo z powierzchni (wszystko dzieje się w tle).

for(int i=0;i<100;i++){
        IOMobileFramebufferConnection connect;
        kern_return_t result;
        IOSurfaceRef screenSurface = NULL;

        io_service_t framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleH1CLCD"));
        if(!framebufferService)
            framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleM2CLCD"));
        if(!framebufferService)
            framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleCLCD"));

        result = IOMobileFramebufferOpen(framebufferService, mach_task_self(), 0, &connect);

        result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &screenSurface);

        uint32_t aseed;
        IOSurfaceLock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
        uint32_t width = IOSurfaceGetWidth(screenSurface);
        uint32_t height = IOSurfaceGetHeight(screenSurface);
        m_width = width;
        m_height = height;
        CFMutableDictionaryRef dict;
        int pitch = width*4, size = width*height*4;
        int bPE=4;
        char pixelFormat[4] = {'A','R','G','B'};
        dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        CFDictionarySetValue(dict, kIOSurfaceIsGlobal, kCFBooleanTrue);
        CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
        CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bPE));
        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, &size));

        IOSurfaceRef destSurf = IOSurfaceCreate(dict);

        IOSurfaceAcceleratorRef outAcc;
        IOSurfaceAcceleratorCreate(NULL, 0, &outAcc);

        IOSurfaceAcceleratorTransferSurface(outAcc, screenSurface, destSurf, dict, NULL);

        IOSurfaceUnlock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
        CFRelease(outAcc);

        // MOST RELEVANT PART OF CODE

        CVPixelBufferCreateWithBytes(NULL, width, height, kCVPixelFormatType_32BGRA, IOSurfaceGetBaseAddress(destSurf), IOSurfaceGetBytesPerRow(destSurf), NULL, NULL, NULL, &sampleBuffer);

        CMTime frameTime = CMTimeMake(frameCount, (int32_t)5);

        [adaptor appendPixelBuffer:sampleBuffer withPresentationTime:frameTime];

        CFRelease(sampleBuffer);
        CFRelease(destSurf);
        frameCount++;
    }

P.S: Ostatnie 4-5 wierszy kodu jest najbardziej odpowiednie (jeśli chcesz filtrować).

1) Produkowany film ma artefakty. Pracowałem wcześniej nad filmami i już wcześniej spotkałem się z takim problemem. Przypuszczam, że mogą być 2 powody tego:
ja. PixelBuffer przekazywany do adaptera jest modyfikowany lub zwalniany przed zakończeniem przetwarzania (kodowanie + zapis). Może to być spowodowane połączeniami asynchronicznymi. Ale nie jestem pewien, czy to sam problem i jak go rozwiązać.
ii. Przekazywane znaczniki czasu są niedokładne (np. 2 ramki mające ten sam znacznik czasu lub ramkę mającą niższy znacznik czasu niż poprzednia ramka). Wylogowałem się z wartości znacznika czasu i to nie wydaje się być problemem.

2) Powyższy kod nie jest w stanie chwycić powierzchni podczas odtwarzania wideo lub podczas grania w gry. Wszystko, co dostaję, to pusty ekran na wyjściu. Może to być spowodowane dekodowaniem przyspieszonym sprzętowo, które ma miejsce w takich przypadkach.

Wszelkie informacje dotyczące jednej z dwóch części pytań będą naprawdę pomocne. Ponadto, jeśli masz jakieś dobre linki do przeczytania ogólnie na IOSurfaces, proszę opublikuj je tutaj.

questionAnswers(1)

yourAnswerToTheQuestion