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