是否可以在XPC服务中使用AVFoundation和OpenCV?我有这么简单的代码
#include <opencv2/opencv.hpp>
#import <AVFoundation/AVFoundation.h>
@interface AppDelegate(){
cv::VideoCapture m_vidCap;
}
。
//Hacky way of forcing OpenCV to call AVFoundation for the first time
//before the camera arrives
//OpenCV should add a better way of mapping camera indexes to cameras
//This way we force that devices are enumerated in the same order here
//and in their code
m_vidCap.open(-1);
m_vidCap.release();
[AVCaptureDevice devices]; //Force avfoundation "startup"
@autoreleasepool {
std::vector<std::wstring> devices;
// chosen device.
NSArray *osDevices=[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingUTF32LE );
AVCaptureDevice *device;
int did=0;
for(device in osDevices) {
NSString *deviceName=[device localizedName];
NSData* wstrdata = [deviceName dataUsingEncoding : encoding ];
std::wstring cppDeviceName=std::wstring((wchar_t*) [ wstrdata bytes ], [ wstrdata length] / sizeof ( wchar_t ) );
devices.push_back(cppDeviceName);
//NSLog("Device %d: %S at position %ld",did,cppDeviceName.c_str(),device.position);
did++;
}
}
在常规 Cocoa 应用程序中启动时根据需要工作。它将枚举两个摄像头,FaceTime摄像头和USB摄像头。
如果我在我的XPC服务中放置相同的确切代码,它将永远挂起
m_vidCap.open(-1);
并且永远不会进一步执行。
我假设在XPC服务中可以使用的内容有一些限制,但我无法谷歌任何有用的东西。任何意见都非常感谢。感谢
你快到了!我认为AVFoundation需要使用NSRunLoop
,但XPC服务默认使用dispatch_main
。您需要向 XPC 服务的info.plist
文件中的XPCService
键标识的字典值添加一个键。默认情况下,它应该有一个ServiceType
密钥。添加一个 RunLoopType
键,并为其指定字符串值 NSRunLoop
。
有关详细信息,请参阅创建 XPC 服务。
好吧,经过多次尝试并检查苹果的样本,我已经让它工作了。问题是如何创建NSXPCListener
。在我像常规服务一样拥有它之前
NSXPCListener *listener = [NSXPCListener serviceListener];
这行不通。
在我改为
ToolMonitorDelegate *myDelegate = [[ToolMonitorDelegate alloc] initWithHardwareType:HT_Vision];
NSXPCListener *listener = [[NSXPCListener alloc] initWithMachServiceName:bundleId];
listener.delegate = myDelegate;
[listener resume];
[[NSRunLoop currentRunLoop] run];
一切都立即工作。在我看来,OpenCV 需要运行应用程序循环才能正常工作。如果我错了或有其他解释,请纠正我。