2015-02-04 2 views
0

Возможно ли использовать AVFoundation и OpenCV внутри службы XPC? У меня есть такой простой кодXPC Service и AVFoundation

#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++; 
    } 
} 

, который работает по мере необходимости при запуске внутри обычного приложения какао. Он будет перечислять как камеры, так и FaceTime и USB.

Если я помещаю точно такой же код внутри моей службы XPC он будет висеть вечно на

m_vidCap.open(-1); 

и никогда не будет выполняться дальше.

Я предполагаю, что есть некоторые ограничения в отношении того, что можно использовать внутри службы XPC, но я не мог ничего полезного Google. Любой вход очень ценится. Thx

ответ

0

Ну, после многих попыток и проверки образцов из яблока у меня это работает. Проблема заключалась в том, как создается 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 требуется работающий цикл приложений. Исправьте меня, если я ошибаюсь или есть другое объяснение.

+0

Вы используете LaunchAgent или LaunchDaemon? Я решил аналогичную проблему в стандартном XPCService, используя ваш подход, но он работает только при работе с Xcode. При запуске приложения вне Xcode кажется, что подключение к службе завершается с ошибкой. –

+0

в конце я дал использование службы XPC и OpenCV, все работало очень нестабильно, множество исключений, где они не могут просто произойти. После того, как я переместил весь код OpenCV в основное приложение, все работало безупречно. – Eugen

1

Вы почти у цели! Я думаю, что AVFoundation должен использовать NSRunLoop, но службы XPC по умолчанию используют dispatch_main. Вам нужно добавить ключ к значению словаря, указанному ключом XPCService в файлеслужбы XPC. По умолчанию он должен иметь один ключ ServiceType. Добавьте ключ RunLoopType и дайте ему строковое значение NSRunLoop.

Для получения дополнительной информации см. Creating XPC services.

Смежные вопросы