我正在开发一款应用程序,可以从相机中捕获帧并混合在另一个线程更新的图像上。我的问题是每500ms调用一次的图像创建线程会消耗影响另一个线程的峰值计算能力。
这里有一些日志用于澄清:
navigator.navigateTo("search/searchterm")
// `search` is your view name, `searchterm` is the passed param
正如您所见,captureOutput的帧速率超过30 fps。一旦motionCallback创建图像,帧速率就会下降,然后再次上升。请注意,motionCallback()仅在每15个捕获帧中调用一次,因此平均计算能力应该足够了。
captureOutput()正在如下所示的队列上运行:
captureOutput(): used time: 0.027741014957428 , frame rate: 36.0477077545513
captureOutput(): used time: 0.0285720229148865 , frame rate: 34.9992719444091
captureOutput(): used time: 0.0310209989547729 , frame rate: 32.2362281581567
captureOutput(): used time: 0.0268059968948364 , frame rate: 37.3050852733863
captureOutput(): used time: 0.0263729691505432 , frame rate: 37.9176115624965
motionCallback(): starting drawing:
captureOutput(): used time: 0.0376390218734741 , frame rate: 26.5681718127947
motionCallback(): elapesed time: 0.0835540294647217
captureOutput(): used time: 0.0581380128860474 , frame rate: 17.2004502795793
captureOutput(): used time: 0.0364410281181335 , frame rate: 27.4415967836645
captureOutput(): used time: 0.0278580188751221 , frame rate: 35.8963070734734
captureOutput(): used time: 0.0283130407333374 , frame rate: 35.3194137435949
captureOutput(): used time: 0.0271909832954407 , frame rate: 36.7768972947616
captureOutput(): used time: 0.0268760323524475 , frame rate: 37.2078730552999
后来我按照以下方式设置了AVCapture:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.m_captureSessionQueue = DispatchQueue(label: "CaptureSessionOutputQueue", attributes: DispatchQueueAttributes.serial)
}
motionCallback()设置如下:
videoDataOutput.setSampleBufferDelegate(self, queue: self.m_captureSessionQueue)
以后:
let interval = 0.4
if m_manager.isDeviceMotionAvailable {
m_manager.showsDeviceMovementDisplay = true
m_manager.deviceMotionUpdateInterval = interval
// XArbitraryCorrectedZVertical
m_manager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xArbitraryCorrectedZVertical , to: OperationQueue.main, withHandler: motionCallback)
print("viewDidLoad(): CM initialized !")
}
像这样和generateImage():
func motionCallback(_ motion: CMDeviceMotion?, error: NSError?) -> Void {
guard let mot = motion else {return}
print("motionCallback(): starting drawing: ")
let start = NSDate() // <<<<<<<<<< Start time
self.m_instrview?.update(attitude: mot.attitude)
self.m_overlayImage = CIImage(image: self.m_instrview!.generateImage()!)
let end = NSDate() // <<<<<<<<<< end time
let timeInterval: Double = end.timeIntervalSince(start as Date)
print("motionCallback(): elapesed time: ", timeInterval)
}
我的想法是每次CoreMotion系统获取更新时都会创建一个新的图像。
我的问题是如何平衡motionCallback()的计算时间,以便它不消耗导致帧速率下降的峰值cpu功率?所以我会接受它运行10倍以上但在此期间只消耗1/10的CPU。
有关如何控制这一点的任何想法?
由于 克里斯
答案 0 :(得分:1)
创建一个异步队列(使用dispatch_queue_create),其优先级低于帧捕获的优先级。在此优先级较低的队列上运行motionCallback。
您在主队列上运行了motionCapture方法,主队列在主线程上运行其任务。不要那样做。
这一行错了:
m_manager.startDeviceMotionUpdates(
using: CMAttitudeReferenceFrame.xArbitraryCorrectedZVertical ,
to: OperationQueue.main,
withHandler: motionCallback)
更改为:参数。
您需要创建一个新的串行队列,其优先级低于您创建的CaptureSessionOutputQueue,并将其传递给上面的to:参数。
我刚刚开始学习Swift 3,所以我还没有创建调度队列的新代码的语法。