Захват экрана iOS RPBroadcastSampleHandler вызывает некоторые плохие видеокадры (yuv nv12), когда частота кадров на экране высока?

Я работаю над захватом экрана и записью на iOS, он основан на ReplayKit и RPBroadcastSampleHandler, кадр видео и аудио был обратным вызовом в processSampleBuffer:withType:. это хорошо, если экран был неподвижен, но когда он движется, будет обратный вызов плохих кадров. Это похоже на то, что кадр был разделен.

Я просто сбрасываю кадр и возвращаюсь, и дамп асинхронный, чтобы избежать блокировки. код был очень прост:

      

extension CVPixelBuffer{
    func asyncDump(_ f:UnsafeMutablePointer<FILE>){
        NSLog("dump a frame.")
        let planeCount = CVPixelBufferGetPlaneCount(self)
        for plane in 0 ..< planeCount {
            let source      = CVPixelBufferGetBaseAddressOfPlane(self, plane)
            let height      = CVPixelBufferGetHeightOfPlane(self, plane)
            let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(self, plane)
            let planeSize   = height * bytesPerRow

            let rawFrame = malloc(planeSize)
            memcpy(rawFrame, source, planeSize)
            let f = f
            DispatchQueue.global(qos: .default).async{
                fwrite(rawFrame,1, planeSize,f)
                free(rawFrame);
                NSLog("dump a frame done.")
            }
        }
    }
}

    override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
        if (DUMP_YUV){
            if RPSampleBufferType.video != sampleBufferType{
                return
            }
        }
        switch sampleBufferType {
        case RPSampleBufferType.video:


            // Handle video sample buffer
            videoFrames+=1
            if let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
                let planeCount = CVPixelBufferGetPlaneCount(imageBuffer)
                let height = UInt32(CVPixelBufferGetHeight(imageBuffer))
                let width =  UInt32(CVPixelBufferGetWidth(imageBuffer))
                printFPS("video-\(width)x\(height)")
                CVPixelBufferLockBaseAddress(imageBuffer, [.readOnly])
                defer { CVPixelBufferUnlockBaseAddress(imageBuffer, [.readOnly]) }
                
                if (DUMP_YUV){
                    if (videoFrames % 150 == 0){// dump 1 in 150 to avoid too much io.
                        if let f = f{
                            imageBuffer.asyncDump(f)
                        }
                    }
                    return
                }
...


один из плохих кадров во вложении. Я также обнаружил, что при обратном вызове с плохим кадром частота кадров обратного вызова была очень высокой, до 90 кадров в секунду, и не было никакого метода или параметра для настройки этой частоты кадров. это очень запутанно, и очень мало информации об этом в Интернете.

0 ответов

Другие вопросы по тегам