Захват экрана 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 кадров в секунду, и не было никакого метода или параметра для настройки этой частоты кадров. это очень запутанно, и очень мало информации об этом в Интернете.