Как я могу создать поток, который может обрабатывать все захваченные видеокадры в фоновом режиме? - PullRequest
2 голосов
/ 27 января 2020

У меня есть функция, которая перебирает видео и извлекает каждый кадр как 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


            }
        }



    }
...