我正在创建一个c++库,用于iOS (是的,不幸的是它必须是C++),它使用AVCaptureSession捕获视频帧,视频帧是通过captureOutput回调传递的。C++库是我的可交付产品。我有一个可可触摸应用程序来测试/演示它。看起来是这样的:
(测试应用程序)<- (c++ lib(AVFoundation回调))
测试应用程序有UI控件,并负责几乎所有的图形。c++库通过OpenGL将帧呈现给UIView。
你在听我说吗?好的
好的,首先,用户按一个UIButton,它会调用我的库。这个调用需要10秒或更长时间才能完成。因此,如果我将调用直接放在按钮单击后,UI将被阻塞,直到库函数返回:
-(IBAction)hBut:(id)sender{
[myLib foo]; // takes 10+ seconds to return
}这不是好事。接下来我尝试的是生成一个线程来调用lib:
-(void)callIntoLib{
[myLib foo];
}
-(IBAction)hBut:(id)sender{
[NSThread detach..:myLib selector:foo object:nil];
}这不再阻止用户界面,但现在视频帧回调功能从未触发(AVCaptureSession的captureOutput)。似乎主NSRunLoop已经被阻塞了。
接下来,我尝试了同样的方法,但是对于Grand Central Dispatch:
-(IBAction)hBut:(id)sender{
_myQueue = dispatch_queue_create("com.domain.me", NULL); // member variable
dispatch_async(_myQueue,
^{
[myLib foo];
});
}这有着同样的行为。也就是说,视频帧的回调不会触发。差劲的
为什么在第二和第三种情况下主要的NSRunLoop被阻塞?有没有办法把队列和它联系起来?
这有道理吗?
发布于 2011-12-23 00:35:09
主线程本身运行它的runLoop,因此在第一种情况下,相机事件被传递到您的库中。自定义线程不运行runLoop,您应该自己运行。
-(void)callIntoLib {
[myLib foo];
self.callIntoLibExecuted = YES;
}
-(void)threadBody {
@autoreleasepool {
self.callIntoLibExecuted = NO;
[self performSelector:@selector(callIntoLib)
onThread:[NSThread currentThread]
withObject:nil
waitUntilDone:NO];
while (!self.callIntoLibExecuted)
{
@autoreleasepool {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
}
}
-(IBAction)hBut:(id)sender {
[NSThread detachNewThreadSelector:@selector(threadBody)
toTarget:self withObject:nil];
}发布于 2011-03-02 00:34:29
此示例代码仅使用GCD串行队列上的AVCaptureVideoDataOutput -setSampleBufferDelegate:queue:。AVCaptureSession似乎必须与RunLoop一起使用。您需要在线程上执行自己的RunLoop,或者尝试将C++库作为示例代码进行修改。
https://stackoverflow.com/questions/5162043
复制相似问题