У меня есть функция, которая перебирает видео и извлекает каждый кадр как CVPixelBuffer.
Каждый кадр отображается в представлении без проблем.
Я хочу отправить каждый кадр в отдельную очередь потока / отправки, чтобы выполнить некоторую обработку изображения в фоновом режиме, не мешая воспроизведению видео.
В настоящее время моя архитектура DispatchQueue выглядит следующим образом:
Пользовательская очередь одновременной отправки, которая захватывает каждый кадр из видео. Как только кадр захватывается, он отправляется в основную очередь для отображения. Затем я создал другой поток в первом настраиваемом потоке, который должен обрабатывать изображения.
У меня проблема в том, что эта тема, кажется, зависит от скорости воспроизведения каждого кадра. Поэтому, если я по какой-то причине воспроизводлю видео с номинальной скоростью или даже быстрее, не все кадры обрабатываются или даже отправляются в фоновую очередь. Видео отображается нормально в 2 раза от номинальной частоты кадров. Однако, чтобы обработать каждый кадр в отдельной очереди, мне нужно снизить скорость воспроизведения почти до 1/2 скорости.
Вот код:
func processFrames () {
let workingQueue = DispatchQueue(label: "workingQueue", qos: .userInitiated, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
let detectQueue = DispatchQueue(label: "detectQueue", qos: .userInitiated, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
var index = 0
workingQueue.async {
while self.start {
//Get frame as a CVPixelBuffer
guard let pixelBuffer = self.videoOutput.copyPixelBuffer(forItemTime: self.playerItem.currentTime(), itemTimeForDisplay: nil)
else {
return
}
// Display frame to screen
self.display(pixelBuffer)
//Process images in different thread - Index and currentTime used to check if each frame is being processed
detectQueue.async {
self.sceneDetector(pixelBuffer, time: self.playerItem.currentTime(), index: index)
}
//playback frame rate in denominator
usleep(useconds_t(1000000/40))
// Advance video 1 step
self.playerItem.step(byCount: 1)
index += 1
}
}
}