-->

IOSurfaces - 人工制品视频和无法抓取视频面(IOSurfaces - Artefact

2019-07-17 19:20发布

这是一个2部分的问题。 我有以下的代码的工作,其抓住当前显示表面和创造出的表面的一个视频(一切发生在背景中)。

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++;
    }

PS:最后4-5行代码是最相关的(如果你需要进行筛选)。

1)所产生的视频有假象。 我已经在视频曾任职也碰到了以前这样的问题也是如此。 我想可能有2个方面的原因:
一世。 传递给适配器的PixelBuffer是越来越修改或释放前处理(编码+写作)完成。 这可能是由于异步调用。 但我不知道这本身就是问题,以及如何解决它。
II。 所传递的时间戳是不准确的(具有相同的时间戳或具有比前一帧的下时间戳的帧例如2帧)。 我登录了时间戳值,这似乎并不成为问题。

2)当视频播放上面的代码是不是能够抓住表面,或当我们玩游戏。 我得到的是输出一个空白屏幕。 这可能是由于这种情况发生在这种情况下硬件加速解码。

在任的2个部分的问题的任何投入将是很有益的。 此外,如果您有任何联系好于一般的IOSurfaces阅读,请不要张贴在这里。

Answer 1:

我做了一些实验,并得出结论认为,从内容复制正在改变甚至在内容传输完成屏幕表面(来电IOSurfaceAcceleratorTransferSurface())。 我使用的是锁(尝试异步和只读),但它是由iOS的覆盖。 我改变了锁定/解锁部件之间的代码为以下最小:

IOSurfaceLock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
aseed1 = IOSurfaceGetSeed(screenSurface);
IOSurfaceAcceleratorTransferSurface(outAcc, screenSurface, destSurf, dict, NULL);
aseed2 = IOSurfaceGetSeed(screenSurface);
IOSurfaceUnlock(screenSurface, kIOSurfaceLockReadOnly, &aseed);

该GetSeed功能告知用户,如果表面的内容发生了变化。 而且,我记录一个计数指示的帧的量,种子变化的数量。 计数是非零。 所以,下面的代码解决了这个问题:

if(aseed1 != aseed2){
//Release the created surface
continue; //Do not use this surface/frame since it has artefacts
}

然而,这因为许多帧/表面由于文物拒绝不影响性能。 任何添加/更正这会有所帮助。



文章来源: IOSurfaces - Artefacts in video and unable to grab video surfaces