2011-03-15 5 views
0

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

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

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

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

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

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

ответ

2

Мне нужно было сделать практически то же самое, что и вы, только с непрерывным видеодисплеем от камеры FireWire. В моем случае я использовал libdc1394 library для выполнения настройки захвата кадра и настройки камеры для наших камер 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 есть extensions you can use, чтобы предоставить эти кадры в виде текстур с использованием DMA для лучшей производительности.

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

0

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

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

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

+0

В настоящее время невозможно изменить параметры экспозиции, усиления и т. Д. Подключенной камеры FireWire через API-интерфейсы QTKit Capture (дубликат rdar: // 5760371 «Возможность установки яркости, усиления и т. Д. Для камер в QTKit Capture API ", если вам нужна эта функциональность). –

+0

Я столкнулся с следующим примером: «Какао - моя подруга», используя QTKit: [link] http://www.cimgf.com/2008/02/23/nsoperation-example/ Это выглядит многообещающим. Я также использую материал libdc1394, и я добрался до того места, где похоже, что я захватил изображение. У меня возникли проблемы с доступом к данным в форме, которую я могу использовать (перевод указателя на unsigned char в массив из 16-битных целых чисел из 14-битной камеры, в конечном счете для сохранения в виде файла tiff ...) –

+0

Если вы хотите абсолютный контроль, метод Брэда - это разумный подход, но я действительно думаю, что QTKit - это путь. Отлично, чтобы использовать NSOperation для этого, но это так быстро, может быть нет необходимости использовать отдельный поток. –

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