카메라의 프레임을 캡처하고 다른 스레드가 업데이트 한 이미지를 혼합하는 앱을 개발 중입니다. 내 문제는 매 500ms마다 호출되는 이미지 작성 스레드가 다른 스레드에 영향을 미치는 피크 컴퓨팅 성능을 소모한다는 것입니다. 여기GCD 설정 예약/스레드 간의 우선 순위
설명에 대한 일부 로그 :
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
당신이 captureOutput은 30 fps의 프레임 속도를 가지고 볼 수 있듯이. motionCallback이 이미지를 생성하자마자 프레임 속도가 떨어지고 다시 올라갑니다. motionCallback()은 매 15 번째 캡처 프레임마다 호출되므로 평균 컴퓨팅 성능이 충분해야합니다.
captureOutput()이 같이 생성 된 큐에서 실행되고 :
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.m_captureSessionQueue = DispatchQueue(label: "CaptureSessionOutputQueue", attributes: DispatchQueueAttributes.serial)
}
나중에 나는 설정 AVCapture에서이 같은 :
videoDataOutput.setSampleBufferDelegate(self, queue: self.m_captureSessionQueue)
motionCallback()는 다음과 같이 설정 :
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 !")
}
이상 :
이 같은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)
}
및 generateImage() :
func generateImage() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main().scale)
drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
아이디어는 CoreMotion 시스템은 내게 새로운 이미지를 생성합니다 업데이 트를 얻을 때마다 만드는 것입니다.
제 질문은 어떻게 프레임 속도가 떨어지는 피크 CPU 전력을 소모하지 않도록 motionCallback()의 계산 시간을 평균 할 수 있습니까? 그래서 나는 그것을 10 배 더 길게 실행하지만 그 시간 동안 CPU의 1/10만을 소모한다고 받아 들일 것입니다.
어떻게 통제 할 수 있었는지 아이디어가 있으십니까?
감사 크리스
모션 콜백은 메인 큐에 있으며, 이는 CPU 집약적 인 함수 인'generateImage' 호출을 포함합니다.이것을 백그라운드 대기열로 보내면 기본 대기열에서 UI 업데이트를 수행해야합니다. – Paulw11
예, 정확하게 문제입니다. CPU 집약 기능은 반드시 메인 스레드에서 호출되어야합니다. 따라서 motionCallBack의 우선 순위를 낮출 수 없다면 캡쳐 스레드의 우선 순위를 정해야합니다. 어떻게해야합니까? – Chris
메인 스레드에서 CPU 집중 기능을 호출해야하는 이유는 무엇입니까? generateImage는 CPU 집중이지만 백그라운드 스레드에서 실행할 수 있습니다. 완료되면 주 스레드에 CIImage 할당을 전달하십시오. 코어 모션 이벤트 처리를 위해 우선 순위가 낮은 스레드 사용 – Paulw11