Должен ли я использовать NSOperation или NSRunLoop? - PullRequest
0 голосов
/ 15 марта 2011

Я пытаюсь отслеживать поток видео с камеры FireWire.Я создал интерфейс Interface Builder с кнопками и NSImageView.В то время как мониторинг изображения происходит в бесконечном цикле, я хочу:

  • изменить некоторые параметры камеры на лету (усиление, гамма и т. Д.)
  • , чтобы монитор остановился,Я могу сохранить изображение в файл (установить флаг, который останавливает цикл while)

Используя функции кнопок, я не смог зациклить монитор видеокадра, все еще ища нажатие кнопки(очень похоже на использование функции нажатия клавиш из C.) Имеются две опции:

  1. Инициировать новый цикл выполнения (для которого я не могу получить автозапуск для функции ...)
  2. Инициируйте NSOperation - как мне сделать это таким образом, чтобы я мог соединиться нажатием кнопки XCode?

Документация очень тупая о создании таких объектов.Если я создаю NSOperation в соответствии с примерами, которые я обнаружил, то, похоже, нет способа связаться с ним с помощью объекта из Interface Builder.Когда я создаю NSRunLoop, я получаю ошибку утечки объекта и не могу найти пример того, как создать автозапуск, который фактически отвечает на созданный мной RunLoop.Не говоря уже о том, что я даже не пытался выбрать, какие объекты отбираются с помощью вторичного цикла выполнения ...

Поскольку Objective C (очевидно!) Не является моим родным языком, я ищу решения с маленькими шагами,извините сказать ... заранее спасибо

Ответы [ 2 ]

2 голосов
/ 16 марта 2011

Мне нужно было делать почти то же самое, что и вы, только с непрерывным отображением видео с камеры FireWire.В моем случае я использовал библиотеку libdc1394 для выполнения захвата кадра и настройки свойств камеры для наших камер FireWire.Я знаю, что вы также можете сделать это, используя некоторые функции Carbon Quicktime, но я обнаружил, что libdc1394 немного проще для понимания.

Для цикла захвата видео я попробовал несколько разных подходов, от отдельногопоток, который опрашивает камеру и имеет блокировки вокруг общих ресурсов, чтобы использовать один NSOperationQueue для взаимодействия с камерой, и, наконец, остановился на использовании CVDisplayLink для опроса камеры способом, который соответствует частоте обновления экрана.

CVDisplayLink настраивается с использованием следующего кода:

CGDirectDisplayID   displayID = CGMainDisplayID();  
CVReturn            error = kCVReturnSuccess;
error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink);
if (error)
{
    NSLog(@"DisplayLink created with error:%d", error);
    displayLink = NULL;
}
CVDisplayLinkSetOutputCallback(displayLink, renderCallback, self);  

и вызывает следующую функцию для запуска поиска нового кадра камеры:

static CVReturn renderCallback(CVDisplayLinkRef displayLink, 
                               const CVTimeStamp *inNow, 
                               const CVTimeStamp *inOutputTime, 
                               CVOptionFlags flagsIn, 
                               CVOptionFlags *flagsOut, 
                               void *displayLinkContext)
{
    return [(SPVideoView *)displayLinkContext renderTime:inOutputTime];
}

CVDisplayLink запускается и останавливаетсяиспользуя следующее:

- (void)startRequestingFrames;
{
    CVDisplayLinkStart(displayLink);    
}

- (void)stopRequestingFrames;
{
    CVDisplayLinkStop(displayLink);
}

Вместо того, чтобы использовать блокировку связи камеры FireWire, всякий раз, когда мне нужно настроить экспозицию, усиление и т. д., я изменяю соответствующие переменные экземпляра и устанавливаю соответствующие биты в переменной флагачтобы указать, какие настройки изменить.При следующем извлечении кадра метод обратного вызова из CVDisplayLink изменяет соответствующие параметры в камере, чтобы соответствовать локально сохраненным переменным экземпляра, и сбрасывает этот флаг.

Отображение на экране обрабатывается с помощью NSOpenGLView (CAOpenGLLayerпредставил слишком много визуальных артефактов при обновлении с такой скоростью, и его обратные вызовы обновления выполнялись в основном потоке).У Apple есть несколько расширений , которые вы можете использовать для предоставления этих кадров в качестве текстур с использованием DMA для повышения производительности.

К сожалению, ничего из того, что я здесь описал, не является материалом начального уровня.У меня есть около 2000 строк кода для этих функций обработки камеры в нашем программном обеспечении, и это заняло много времени, чтобы разобраться.Если бы Apple могла добавить ручные настройки камеры в API QTKit Capture, я бы почти все это удалила.

0 голосов
/ 15 марта 2011

Если все, что вы пытаетесь сделать, это посмотреть / захватить выход подключенной камеры, ответ, вероятно, не тот.

Используйте QTCaptureView QTKit .Задача решена.Хотите захватить кадр ?Тоже нет проблем.Не пытайтесь свернуть свои собственные вещи - материал QTKit оптимизирован и является частью ОС.Я почти уверен, что вы можете влиять на свойства камеры так, как вам хотелось бы, но если нет, план B. должен работать.

План b: использовать запланированный, повторяющийся NSTimer , чтобы попросить QTKit захватить кадрвремя от времени (как указано выше) и применяйте манипуляции с изображениями к кадру (возможно, с помощью Core Image ) перед отображением в NSImageView.

...