XPC 服务和 AVFoundation
XPC Service and AVFoundation
是否可以在 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 服务中可以使用的内容有一些限制,但我无法 google 任何有用的东西。
非常感谢任何输入。
谢谢
好吧,经过大量尝试并检查来自 apple 的样本后,我已经开始工作了。问题是 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 需要 运行 应用程序循环才能正常工作。如果我错了或有其他解释,请纠正我。
快完成了!我认为 AVFoundation 需要使用 NSRunLoop
,但 XPC 服务默认使用 dispatch_main
。您需要向 XPC 服务的 info.plist
文件中的 XPCService
键标识的字典值添加一个键。默认情况下,它应该有一个 ServiceType
键。添加一个 RunLoopType
键,并给它一个字符串值 NSRunLoop
.
有关详细信息,请参阅 Creating XPC services。
是否可以在 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 服务中可以使用的内容有一些限制,但我无法 google 任何有用的东西。 非常感谢任何输入。 谢谢
好吧,经过大量尝试并检查来自 apple 的样本后,我已经开始工作了。问题是 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 需要 运行 应用程序循环才能正常工作。如果我错了或有其他解释,请纠正我。
快完成了!我认为 AVFoundation 需要使用 NSRunLoop
,但 XPC 服务默认使用 dispatch_main
。您需要向 XPC 服务的 info.plist
文件中的 XPCService
键标识的字典值添加一个键。默认情况下,它应该有一个 ServiceType
键。添加一个 RunLoopType
键,并给它一个字符串值 NSRunLoop
.
有关详细信息,请参阅 Creating XPC services。